代码之家  ›  专栏  ›  技术社区  ›  fred basset

需要同步布尔成员变量的设置吗?

  •  13
  • fred basset  · 技术社区  · 14 年前

    嘿,我正在处理一些我继承的代码,看起来一个线程正在设置一个布尔成员变量,而另一个线程正在进行while循环检查。这真的有效吗,或者我应该将其更改为对布尔变量使用同步的getter或setter吗?

    5 回复  |  直到 13 年前
        1
  •  7
  •   Robert Harvey    13 年前

    在读写像bool或int这样的原始语句时,将它们声明为volatile就足够了。当一个线程读取时,另一个线程就完成了写入。变量永远不会处于无效状态。

    总的来说,不稳定的关键词 Java的文档记录不足,理解甚少,很少使用。使 更糟糕的是,它的正式定义实际上改变了Java 5。 本质上,volatile用于指示变量的值将 由不同的线程修改。

    声明一个易失性Java变量意味着:

    1. 此变量的值将 从不在本地缓存线程:全部 读和写将直接转到 “主存”;
    2. 访问变量的作用是 虽然它被封闭在 同步块,同步打开 本身。

    我们在第二点中说“好像是”,因为对程序员来说 至少(可能在大多数JVM实现中)没有实际的 涉及锁定对象。

    http://www.javamex.com/tutorials/synchronization_volatile.shtml

        2
  •  2
  •   Tom Hawtin - tackline    14 年前

    几乎可以肯定的是,您需要在更高的级别上添加锁。只加 synchronized 对字段的单次访问几乎没有帮助。如果组件操作是独立的线程安全的,那么复合操作将不是线程安全的。

    例如,考虑删除线程安全文档的内容。文档提供了两个相关的线程安全操作:删除两个索引之间的内容和一个长度操作。所以你得到长度,从零到长度删除,对吗?嗯,这是一个竞赛,因为文档在读取长度和删除内容之间可能会改变长度。在给定操作的情况下,无法使操作线程安全。(示例取自Swing文本。)

        3
  •  0
  •   Alexander Pogrebnyak    14 年前

    如果使用Java 1.5 +,则应该使用 Condition 同步原语。

    如果你遵循链接,它有一个关于如何使用它的很好的例子。

        4
  •  0
  •   nos    14 年前

    如果它是一个普通的布尔函数,那么它就不能保证工作,其中一个线程可能不会因为Java的内存模型而看到更新的布尔值。

    请记住,如果读取此布尔值的线程依赖于布尔值的前一个值,则这些值都不会“起作用”——它可能会错过对该布尔值的更改,例如。

    线程1:

    while(foo.myVolatileBoolean) {
     ... 
    }
    

    线程2:

    foo.myVolatileBoolean = false; //thread 1 might never catch thisone.
     ... 
    foo.myVolatileBoolean = true;
    

    如果这是一个问题,并且您需要监视对布尔值的更改,请考虑使用wait()/notify()或 Condition

        5
  •  -1
  •   bjg    14 年前

    我建议将布尔值声明为volatile,并同步读写访问。