当我们仅对变量执行读取操作时应使用Volatile,因为一个线程更新的值对另一个线程可见,即使前一个线程丢失CPU并退出synchronized块。那是对的吗?当需要使用原子行为时,将使用原子基元。例如 -
if (volatileBoolean) {
volatileBoolean = !volatileBoolean;
}
假设volatileBoolean的值为true。一个线程将volatileBoolean检查为true并输入if block,第二个线程将volatileBoolean的值视为true,同时输入if块。现在,假设第一个线程将假值(!volatileBoolean)分配给volatileBoolean变量并丢失CPU,因此退出if块。第二个线程将volatileBoolean视为false,将其指定为true。
这是应该使用AtomicBoolean的情况吗?如果是,为什么不能通过使用synchronized来处理?
synchronized(this){
if (volatileBoolean) {
volatileBoolean = !volatileBoolean;
}
}
答案 0 :(得分:2)
这是应该使用AtomicBoolean的情况吗?
是的。
如果是,为什么不能通过使用synchronized来处理?
它是功能等效的,但AtomicBoolean不使用锁,在中等争用下可以更有效。请参阅此other question - 它会查看AtomicInteger,但结论也直接适用于AromicBoolean。
答案 1 :(得分:0)
是的,这是你想要使用AtomicBoolean的情况。这是一种非常好且安全的方式来实现您提到的那种同步(而不是自己动手)并且速度更快。另请参阅this link以与使用volatile boolean作为替代进行比较。
答案 2 :(得分:0)
当我们仅对变量执行读取操作时应该使用Volatile,因为一个线程更新的值对另一个线程可见,即使前一个线程丢失CPU并退出synchronized块。这是对的吗?
这是应该使用AtomicBoolean的情况吗?如果是,为什么不能通过使用synchronized?
来处理AtomicBoolean在内部使用volatile int和CAS操作来提供可见性和原子性。
<强> AtomicBoolean.java 强>
public class AtomicBoolean implements java.io.Serializable {
private volatile int value;
/**
* Creates a new {@code AtomicBoolean} with the given initial value.
*
* @param initialValue the initial value
*/
public AtomicBoolean(boolean initialValue) {
value = initialValue ? 1 : 0;
}
Java语言还提供了另一种较弱的同步形式,即volatile变量,以确保这一点 对变量的更新可预测地传播到其他传播。当一个字段被声明为volatile时,编译器和 运行时会注意到这个变量是共享的,并且对它的操作不应该与其他操作重新排序 记忆操作。 仅在简化实施和验证同步策略时使用volatile变量;避免使用 验证正确性时的volatile变量需要对可见性进行微妙推理。易挥发的好用途 变量包括确保自己状态的可见性,它们所引用的对象的可见性,或指示一个 发生了重要的生命周期事件(例如初始化或关闭)。
答案 3 :(得分:0)
AtomicBoolean和任何AtomicSomething都是使用volatile实现的。唯一的区别是那些AtomicSomething包含一些没有synchronized关键字进行同步的方法,例如compareAndSet或lazySet。所以你应该在你的情况下使用AtomicBoolean。