Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么要锁定线程安全的集合?_Java_Collections_Synchronization - Fatal编程技术网

Java 为什么要锁定线程安全的集合?

Java 为什么要锁定线程安全的集合?,java,collections,synchronization,Java,Collections,Synchronization,java.util.concurrent提供了许多线程安全集合,如ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet和ConcurrentLinkedQueue。这些集合应该通过允许并发访问数据结构的不同部分来最小化争用 Java还具有同步包装器,允许并发访问非线程安全的集合,如HashMap和Arraylist Map<KeyType, ValType> m = Collections.synchronized

java.util.concurrent提供了许多线程安全集合,如
ConcurrentHashMap
ConcurrentSkipListMap
ConcurrentSkipListSet
ConcurrentLinkedQueue
。这些集合应该通过允许并发访问数据结构的不同部分来最小化争用

Java还具有同步包装器,允许并发访问非线程安全的集合,如
HashMap
Arraylist

Map<KeyType, ValType> m = Collections.synchronizedMap(new HashMap<KeyType, ValType>());
Map m=Collections.synchronizedMap(新的HashMap());
在处理这些线程安全的集合时,我们还需要执行客户端锁定吗?特别是,在对它们进行迭代时

 Set<KeyType> s = m.keySet();  
 synchronized(m) {
     for (KeyType k : s)
         foo(k); 
 }
Set s=m.keySet();
同步(m){
用于(钥匙类型k:s)
傅(k),;
}
在这种情况下,是否仅为某些类型的操作提供线程安全性

有没有一种方法可以在不使用同步的情况下提供线程安全的集合?我熟悉volatile关键字,它可能用于非原子操作的原语值

1)是的,您需要在迭代时执行客户端锁定,但大多数其他方法不需要您这样做。请参阅

2) 所以,第二个问题的答案自动变为“是”。您可以在文档中看到哪些操作是线程安全的(大多数是线程安全的)

3) 关于不使用同步的线程安全收集:对于开发平台的专业开发人员团队来说,这听起来可能是一项困难的任务。但实际上,在多核环境和积极优化的时代,这是一场噩梦。在功能(听起来可能和这个一样简单)和性能(处理器缓存中的同步需要花费大量时间)之间总会有一个权衡。请参考Angelica Langer的(关于java内存模型)


希望这有帮助。

您是否阅读了
synchronizedMap
的文档?它至少回答了您的一个问题…并发集合不使用synchronized关键字,并且是线程安全的。