【问题标题】:Why lock Thread safe collections?为什么要锁定线程安全集合?
【发布时间】:2014-02-25 10:20:29
【问题描述】:

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

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

Map<KeyType, ValType> m = Collections.synchronizedMap(new HashMap<KeyType, ValType>());

在处理这些线程安全集合时,我们还需要执行客户端锁定吗?特别是在对它们进行迭代时?

 Set<KeyType> s = m.keySet();  
 synchronized(m) {
     for (KeyType k : s)
         foo(k); 
 }

在这种情况下,是否只为某些类型的操作提供线程安全?

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

【问题讨论】:

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

标签: java collections synchronization


【解决方案1】:

1) 是的,您需要在迭代时执行客户端锁定,但大多数其他方法不需要您这样做。请参考Explain synchronization of collections when iterators are used?

2) 所以回答你的第二个问题会自动变成是。您可以在文档中查看哪些操作是线程安全的(大部分都是)。

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

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-27
    • 2021-12-19
    • 2011-09-25
    • 2011-06-09
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多