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

时间:2010-06-30 23:42:06

标签: java multithreading

嘿所有,我正在处理我继承的一些代码,看起来一个线程正在设置一个布尔成员变量,而另一个线程在while循环中检查它。这实际上是否可以正常工作,还是应该将其更改为在布尔变量上使用同步的getter或setter?

5 个答案:

答案 0 :(得分:7)

在读取和写入bool或int这样的原语的情况下,将它们声明为volatile是很多的。当一个线程读取时,另一个线程将完成写入。变量永远不会处于无效状态。

  

总的来说,挥霍性关键字可能是公平的   Java文档记录很少,理解不充分,很少使用。要做   更糟糕的是,它的正式定义实际上已经改变了Java 5。   从本质上讲,volatile用于表示变量的值   被不同的线程修改。

     

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

     
      
  1. 此变量的值将为   永远不会被缓存线程本地:所有   读写将直接进行   “主要记忆”;
  2.   
  3. 对变量的访问充当   虽然它被包含在一个   同步块,同步   本身。
  4.         

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

         

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

如果您使用java 1.5+,则应使用Condition同步原语。

如果您点击链接,它就有一个很好的例子来说明如何使用它。

答案 3 :(得分:0)

如果它是一个普通的布尔值,它不能保证工作,由于java的内存模型,其中一个线程可能看不到更新的布尔值,你可以

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

线程1:

while(foo.myVolatileBoolean) {
 ... 
}

线程2:

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

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

答案 4 :(得分:-1)

我建议将布尔值声明为volatile,并且读取和写入访问是同步的