本地变量在Java中是线程安全的。使用方法线程中声明的hashmap
是否安全?
例如 -
void usingHashMap()
{
HashMap<Integer> map = new HashMap<integer>();
}
答案 0 :(得分:5)
当两个线程在usingHashMap()
运行相同的方法时,它们绝不相关。每个thread
将创建自己的每个局部变量的版本,并且这些变量不会以任何方式相互交互
如果变量不是本地变量,则它们将附加到实例。在这种情况下,运行相同方法的两个线程都看到一个变量,这不是线程安全的。
public class usingHashMapNotThreadSafe {
HashMap<Integer, String> map = new HashMap<Integer, String>();
public int work() {
//manipulating the hashmap here
}
}
public class usingHashMapThreadSafe {
public int worksafe() {
HashMap<Integer, String> map = new HashMap<Integer, String>();
//manipulating the hashmap here
}
}
虽然在usingHashMapNotThreadSafe
的同一个实例上运行的usingHashMapNotThreadSafe
两个线程将看到相同的x。这可能很危险,因为线程正在尝试更改map
!在第二个中,在usingHashMapThreadSafe
的同一个实例上运行的两个线程将看到完全不同的x版本,并且不能相互影响。
答案 1 :(得分:2)
只要未发布对HashMap对象的引用(不传递给另一个方法),它就是线程安全的。
这同样适用于存储在地图中的键/值。它们需要是不可变的(在创建后不能改变它们的状态)或仅在这种方法中使用。
答案 2 :(得分:0)
我认为为了确保完全并发,在任何情况下都应该使用ConcurrentHashMap
。即使它是本地的范围。 ConcurrentHashMap
实施ConcurrentMap
。分区本质上是一种尝试,如documentation中所述:
该表在内部进行分区,以尝试允许指定数量的并发更新而不会发生争用。因为散列表中的放置基本上是随机的,所以实际的并发性会有所不同。理想情况下,您应该选择一个值来容纳与同时修改表一样多的线程。使用比您需要的值更高的值会浪费空间和时间,而显着更低的值可能会导致线程争用。