【问题标题】:Java volatile modifier and synchronized blocksJava volatile 修饰符和同步块
【发布时间】:2010-07-09 17:09:15
【问题描述】:

一个由多个线程访问但仅在同步块内的变量是否需要 volatile 修饰符?如果不是,为什么?

【问题讨论】:

标签: java multithreading synchronized volatile


【解决方案1】:

您不需要在synchronized 内部使用volatile,同步已经保证了在一致使用时(在每次访问时)本地缓存变量的正确行为。

volatile 适用于原始值,并且可以成为对原始类型进行原子访问的一个很好的快捷方式。请注意,从 1.4 开始,JDK 5 中 volatile 的行为发生了变化。

更多信息可以找到here

【讨论】:

    【解决方案2】:

    没有。当您在同步块中工作时,所有缓存的变量都会在访问时同步,因为它会创建内存屏障。

    有关详细信息,请参阅volatile to synchronized 的比较(带讨论)。

    【讨论】:

      【解决方案3】:

      保证在同一对象(或方法)上同步的块不会同时运行。所以只要同步到同一个对象,你的变量永远不会有并发访问,所以不需要特殊处理。

      如果您的访问不同步,那么您就有竞争条件。使变量volatile 对于某些原始变量可能是正确的(我推迟到其他帖子以获得有关 volaitle 的更好信息)。如果这没有用,你几乎肯定有一个错误。

      【讨论】:

      • 为了迂腐,在其他语言中同步并不意味着一致的内存 - 值可能缓存在寄存器或本地内存中,即使访问是同步的,它也可能不是原子/一致的。然而,在 Java 中,synchronized 会自动开启 volatile。
      • 同样迂腐,您可能想到的其他语言 (C/C++) 没有同步线程的内在概念,甚至没有 synchronized 关键字;你必须构造一些类似的互斥锁。你是对的:没有运行时来为你管理内存一致性。这些语言甚至没有为并发内存访问指定任何语义!谢天谢地,Java 很不错,它只是做你期望它做的事情。
      • @YannRamin 如您所说,您同步的变量实际上是易变的,以便在该同步块中对其进行修改?不确定我的解释是否正确,但我在其他地方找不到关于这种效果的描述。
      猜你喜欢
      • 2017-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 2018-05-31
      • 2022-06-13
      • 2013-12-01
      相关资源
      最近更新 更多