Java 静态方法中的类实例是线程安全的吗

Java 静态方法中的类实例是线程安全的吗,java,multithreading,concurrency,thread-safety,Java,Multithreading,Concurrency,Thread Safety,我有一个静态方法,如下所示 public static void foo(){ final ClassA a = new ClassA(); } 我在classA中有两个哈希映射 那些哈希映射是线程安全的吗?类HashMap不是线程安全的 请注意,此实现是不同步的。如果多个线程同时访问此映射,并且至少有一个线程在结构上修改映射,则必须在外部对其进行同步 但是,每次调用代码foo时,都会得到一个新的ClassA,因此调用foo的两个不同线程将访问ClassA的不同实例。假设Cla

我有一个静态方法,如下所示

 public static void foo(){
     final ClassA a = new ClassA();
 } 
我在classA中有两个哈希映射


那些哈希映射是线程安全的吗?

HashMap
不是线程安全的

请注意,此实现是不同步的。如果多个线程同时访问此映射,并且至少有一个线程在结构上修改映射,则必须在外部对其进行同步


但是,每次调用代码
foo
时,都会得到一个新的
ClassA
,因此调用
foo
的两个不同线程将访问
ClassA
的不同实例。假设
ClassA
中的哈希映射不是静态的或共享的,代码应该可以正常工作。

编写代码的方式将使所有线程都可以使用静态方法,因此每个线程都将获得自己的类对象。所以每个类都有自己的哈希映射


但是,如果希望所有线程都具有相同的哈希映射,那么如果
classA
中的
哈希映射是非静态的(为每个新
classA()
创建新的),请尝试将其同步化,然后,您可以从多个线程调用foo,并保证只有一个线程会在为该线程创建的
classA
实例中运行
HashMaps

我不同意(我缺少了什么)

在方法内部创建了ClassA的新实例。即使多个线程访问该方法,每个线程都将有一个唯一的HashMap来处理

如果ClassA是一个实例变量,则情况会有所不同。此外,如果ClassA同时访问映射,则会出现线程问题


此外,如果映射是静态的,则ClassA的多个实例将有权访问它,是的,这将是一种试探。

不清楚您是要使用多个线程访问对象
a
内的哈希映射,还是要使用多个线程调用方法
foo

在第一种情况下,集合的线程安全与外部上下文无关,即它是否在静态上下文中创建。因此,如果您尝试使用多个线程从对象
a
访问哈希映射,则会导致意外行为。您需要使用
同步的
块来管理对它们的访问

在第二种情况下,每个线程在其堆栈上都有一个不同的foo副本,并分配不同的
ClassA
实例。因此,它们不会发生冲突,因为它们将使用不同的
HashMaps


请澄清您正在处理的是哪种情况。

HashMap
不是线程安全的,但假设您从未将实例
a
或其两个哈希映射发布到
foo()
之外,则这三个哈希映射都被限制在一个线程中,不需要是线程安全的


如果确实发布
a
或其哈希映射,或者如果哈希映射是
ClassA
的静态成员,则应确保线程安全。假设没有涉及哈希映射或其他一些状态变量的不变量,您可以简单地使用它们来实现这一点。如果存在这样的不变量,您应该在
ClassA
而不是
foo()

中同步,理想情况下尽可能接近状态变量,但新操作是原子的吗?如果您担心线程安全映射,可以使用Collections.synchronizedMap或ConcurrentHashMap@chance,是的,有一个系统范围的锁,确保两个线程不能同时分配堆内存。不清楚这些映射是如何使用和定义的。HashMap不是线程安全的。但请参见并发哈希映射: