繁体   English   中英

volatile布尔值

[英]volatile boolean

如果我有一个volatile布尔值(让它调用它有效),下面的代码片段是否在Java中是线程安全的?

if (valid)
  return;
valid = true;

或者,我是否需要同步,因为只有在有效时才将其设置为true(因此有效集取决于其当前值)?

这需要同步,因为如果一个线程评估有效为false,然后在赋值之前暂停执行,那么另一个线程出现并且还将有效检查为false,在将valid设置为true之前,您将有两个线程运行代码从这里(大概你不想要)。

使用AtomicBoolean。 可以同时检查和设置实例。

它不是线程安全的。 但如果这是整个代码,那就不重要了。

编辑:全方位的高级替代方案是AtomicBoolean ,它使用低级操作来实现条件更新而不进行同步。

对标志有两种独立的(即非原子)访问,因此除非该线程是唯一对该标志进行写操作的线程, 否则需要进行同步。 即便如此,为了确保未来的变化,同步也可能是件好事。

您的代码不是线程安全的,但它实际上取决于您的其他代码是否安全。

您是否要求只有一个线程执行一次valid = true的代码? 如果是这样,那么你的代码是不是安全的,因为任何数量的线程可以读取false的值valid ,然后最终将其设置为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()循环而不是if()块,所以,你的设计很可能是不正确的:)

根据Brian Goetz的一篇好文章https://www.ibm.com/developerworks/java/library/j-jtp06197/ “只有在一系列有限的情况下才能使用volatile变量而不是锁。以下两个标准都必须满足volatile变量以提供所需的线程安全性:

  • 写入变量不依赖于其当前值。
  • 变量不参与其他变量的不变量。

基本上,这些条件表明可以写入volatile变量的有效值集独立于任何其他程序状态,包括变量的当前状态。“因此它必须与锁同步。它不是线程安全的是。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM