繁体   English   中英

在方法内部声明哈希图

[英]Declaring a hashmap inside a method

局部变量在Java中是线程安全的。 使用在方法线程内部声明的hashmap安全吗? 例如-

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

当两个线程在这里使用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版本,并且不会互相影响。

只要不发布对HashMap对象的引用(不传递给另一个方法),它就是线程安全的。
这同样适用于存储在地图中的键/值。 它们必须是不可变的(创建后不能更改其状态)或仅在此方法内使用。

我认为为确保完全的并发性,无论如何都应使用ConcurrentHashMap 即使它在范围内也是本地的。 ConcurrentHashMap实现ConcurrentMap 分区实质上是一种尝试,如文档中所述:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM