如果我有一个易变的布尔值(让我们把它称为有效的),下面的一段代码是Java中线程安全的吗?或者,我是否需要进行同步,因为只有当它为假时(因此设置的有效取决于其当前值),有效设置为真?)?volatile boolean
回答
这需要同步,因为如果一个线程将有效值设为false,然后在赋值之前暂停执行,则另一个线程会出现,并且在将有效设置为true之前检查有效值为false,您将有两个线程从这里运行代码(这大概是你不想要的)。
编辑:一个全面优越的替代方案是AtomicBoolean
,它使用低级操作来实现无同步的条件更新。
有两个单独的(即非原子)访问标志,因此同步是必要的除非这个线程是唯一一个在标志上执行写操作。即使这样,在未来发生变化的情况下进行同步也可能会很好。
您的代码不是线程安全的,但它确实取决于您的其他代码是否安全。
您是否要求valid = true
之后的代码只能由单个线程执行一次?如果是这样,那么你的代码是不安全的,因为任何数量的线程可以读取valid
的值false
,然后最终将其设置为true
。例如:
if (valid)
return;
// Imagine every single one of your threads stops and blocks here.
// They will all wake up again and set valid to true and then
// execute the code to follow.
valid = true;
但如果你只是想保证valid = true
后的代码由任何线程最多一次执行...那么你有什么是好的。但如果这是你需要的行为,我会通过其他方式实现,因为在这种情况下使用volatile
将看起来像你不知道你在做什么。例如,你可能不会在线程间共享变量valid
,并允许每个线程只执行一次代码。
此外,当有疑问的同时推理同步和易失性...只使用同步。它通常更加清晰,并且会为您提供使用volatile
所需的一切,除非它更容易理解代码的工作原理。
线程安全是一个系统范围的属性。你不能孤立地看一段代码,并把它称为线程安全/不安全。这取决于其他线程如何与它进行交互以及一致性要求是什么。话虽如此,大多数线程安全设计有while()循环,而不是如果()块,这样,你的设计是最有可能不正确:)
通过使用原子或同步操作的线程安全性,而不是使用while循环。你说得对,线程安全是一个系统属性,但如果valid是一个共享变量,这个代码本质上不适合多线程。 – extraneon 2009-12-13 20:55:51
我并不是说while循环使线程安全。我说线程安全代码通常有while循环,if-block通常表示错误。 – irreputable 2009-12-14 03:15:10
据布赖恩戈茨大纸 https://www.ibm.com/developerworks/java/library/j-jtp06197/ “您可以使用挥发性变量,而不是仅在有限的情况下锁定。为了提供期望的线程安全性,必须满足以下两个条件:
- 写入变量不取决于其当前值。
- 该变量不参与其他变量的不变量。
基本上,这些条件状态下可以写入到易失性可变的组有效值是独立于任何其他程序的状态的,包括可变的当前状态。” 所以必须有锁定同步。它不是线程安全的
- 1. sampleVariable As Boolean = My.settings.sampleSettings(boolean dataType)does not work
- 2. Java中boolean和Boolean有什么区别?
- 3. recyclerview的setLayoutFrozen(boolean)和setHasFixedSize(boolean)目的
- 4. volatile关键字
- 5. PHP boolean TRUE/FALSE?
- 6. JavaScript Boolean值,
- 7. JSON golang boolean omitempty
- 8. VARCHAR(1)vs BOOLEAN
- 9. XPath boolean'或'
- 10. boolean algebra article/book
- 11. C#volatile数组项?
- 12. Object == null vs boolean == false
- 13. public boolean removeStudent(int id)
- 14. Boolean对象和JAVA
- 15. 指向易失性数据的指针(*((volatile volatile uint32_t *)0x40000000))
- 16. 爪哇 - volatile变量没有更新
- 17. 精简框架 - Image.FromStream(Stream,Boolean,Boolean)的任何实现?
- 18. java bean boolean提交给json&boolean vs布尔
- 19. 关于该volatile关键字
- 20. volatile如何实际工作?
- 21. volatile变量和订购
- 22. C中的volatile变量
- 23. 哪里可以使用volatile?
- 24. C++ volatile成员函数
- 25. 方法签名中'volatile'?
- 26. volatile __thread,毫无意义?
- 27. Java volatile变量,多线程
- 28. !!boolean是java中的一个原子操作吗?
- 29. Java boolean if-statement up up
- 30. C++返回boolean值95
易失性不会解决_race条件_易失性解决了存储在“有效”中的值与所有其他线程共享_访问valid_的问题,因此如果“有效”不是静态,并且没有静态引用包含“有效”的对象,那么没有其他线程会知道“有效” – Marco 2012-01-11 14:51:43