嘿所有,我正在处理我继承的一些代码,看起来一个线程正在设置一个布尔成员变量,而另一个线程在while循环中检查它。这实际上是否可以正常工作,还是应该将其更改为在布尔变量上使用同步的getter或setter?
答案 0 :(得分:7)
在读取和写入bool或int这样的原语的情况下,将它们声明为volatile是很多的。当一个线程读取时,另一个线程将完成写入。变量永远不会处于无效状态。
总的来说,挥霍性关键字可能是公平的 Java文档记录很少,理解不充分,很少使用。要做 更糟糕的是,它的正式定义实际上已经改变了Java 5。 从本质上讲,volatile用于表示变量的值 被不同的线程修改。
声明一个易变的Java变量意味着:
- 此变量的值将为 永远不会被缓存线程本地:所有 读写将直接进行 “主要记忆”;
- 对变量的访问充当 虽然它被包含在一个 同步块,同步 本身。
醇>我们说第二点“就好像”,因为程序员 至少(并且可能在大多数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,并且读取和写入访问是同步的