在方法内声明散列映射

时间:2014-06-08 15:34:11

标签: java multithreading

本地变量在Java中是线程安全的。使用方法线程中声明的hashmap是否安全? 例如 -

void usingHashMap()
{
    HashMap<Integer> map = new HashMap<integer>();
}

3 个答案:

答案 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中所述:

该表在内部进行分区,以尝试允许指定数量的并发更新而不会发生争用。因为散列表中的放置基本上是随机的,所以实际的并发性会有所不同。理想情况下,您应该选择一个值来容纳与同时修改表一样多的线程。使用比您需要的值更高的值会浪费空间和时间,而显着更低的值可能会导致线程争用。

相关问题