首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用java.util.concurrent类时,我是否应该进行同步以避免可见性问题?

在使用java.util.concurrent类时,我是否应该进行同步以避免可见性问题?
EN

Stack Overflow用户
提问于 2010-10-28 14:49:33
回答 2查看 1.6K关注 0票数 5

当使用任何java.util.concurrent类时,我是否仍然需要同步对实例的访问,以避免不同线程之间的可见性问题?

更详细地阐述这个问题

当使用java.util.concurrent的实例时,有没有可能某个线程修改了该实例(例如,将一个元素放入并发哈希图中),而随后的线程看不到修改?

我的问题源于这样一个事实:如果对值的访问不同步,Java内存模型允许线程缓存这些值,而不是直接从内存获取它们。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-28 14:54:03

在java.util.concurrent包Memory Consistency Properties上,您可以检查该包的Javadoc API:

java.util.concurrent及其子包中所有类的方法将这些保证扩展到更高级别的同步。特别是:

在将一个对象放入任何并发集合之前,线程中的

  • 操作会发生-在从另一个线程中的集合访问或移除该元素之后的操作之前。

...在“释放”同步器方法之前执行

  • 操作,例如

Lock.unlock、Semaphore.release和

CountDownLatch.countDown

发生-在成功的“获取”方法之后的操作之前,例如在另一个线程中的相同同步器对象上的Lock.lock、Semaphore.acquire、Condition.await和CountDownLatch.await。

...

因此,这个包中的类利用一组用于线程控制的类(LockSemaphore等)来确保并发性。这些类以编程方式处理之前发生的逻辑,即管理并发线程的先进先出堆栈,锁定和释放当前和后续线程(即使用Thread.wait()Thread.resume()等)。

然后,(理论上)您不需要同步访问这些类的语句,因为它们以编程方式控制并发线程访问。

票数 3
EN

Stack Overflow用户

发布于 2010-10-28 15:39:37

因为ConcurrentHashMap (例如)被设计为在并发上下文中使用,所以您不需要进一步同步它。事实上,这样做可能会破坏它带来的优化。

例如,Collections.synchronizedMap(...)表示一种使map线程安全的方法,据我所知,它的工作原理是将所有调用包装在synchronized关键字中。另一方面,像ConcurrentHashMap这样的东西会在集合中的元素之间创建同步的“桶”,从而导致更细粒度的并发控制,从而在大量使用的情况下减少锁争用。例如,它也可能不锁定读取。如果你再次使用一些同步访问来包装它,你可能会破坏它。显然,您必须注意所有对集合的访问都是同步的,等等,这是较新的库的另一个优势;您不必担心(就像这样!)

java.lang.concurrent集合可以通过同步来实现它们的线程安全。在这种情况下,语言规范保证了可见性。他们可以在不使用锁的情况下实现一些东西。我不太清楚这一点,但我假设这里也有同样的可见性。

如果你在你的代码中看到了看起来丢失的更新,这可能只是一个竞争条件。像ConcurrentHashpMap这样的东西将为您提供读操作的最新值,而写操作可能尚未写入。这通常是准确性和性能之间的权衡。

重点是;java.util.concurrent stuff就是用来做这些事情的,所以我相信它可以确保可见性,并且不需要使用易失性和/或附加同步。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4040477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档