使用AtomicBoolean而不是synchronized块

时间:2016-03-07 18:53:42

标签: java multithreading java-threads atomicboolean

假设我有一个包含2个实例变量的类和以下方法(针对此问题进行了简化):

private final Object lock = new Object();
private boolean running;

public MyClass() {
    synchronized(lock) {
        running = false;
    }
}
public void methodA() {
    synchronized(lock) {
        running = true;
    }
}
public void methodB() {
    synchronized(lock) {
        if (!running) {
            return;
        }
    }
}

我正在查看此代码,在阅读了AtomicBoolean后,我认为可能适合此处,特别是在查看MyClass构造函数和methodA之后。我对methodB不太确定。

假设这些方法可以被多个线程调用,那么以下是线程安全的吗?:

private AtomicBoolean running;

public MyClass() {
    running = new AtomicBoolean(false);
}
public void methodA() {
    running.set(true);
}
public void methodB() {
    if (!running.get()) {
        return;
    }
}

保证running.get()能否通过running.set(true)running.set(false)从另一个帖子看到更新?

3 个答案:

答案 0 :(得分:2)

在您的示例中,简单的volatile boolean就足够了,因为您似乎只是在执行原子操作。如果您需要compareAndSet

等方法,AtomicBoolean非常有用

因此,在回答您的问题时,是的,当使用volatile booleanAtomicBoolean时,其他线程会看到变量的更新。

答案 1 :(得分:1)

一般来说,这些代码块与getJSON()不相同,因为读取return $this->getJSON($this->postURL("https://www.googleapis.com/geolocation/v1/geolocate?key=$key")); 变量不会创建同步顺序。

想象一下,您的班级中有其他字段methodB,已在方法B中更新:

volatile

然后你有几个线程调用int x = 42

  • 使用synchronized关键字时,所有线程都可以安全地查看更新。
  • 当使用AtomicBoolean / volatile可见性被破坏时

如果没有变量更新的情况,并且任务只是为了保证methodA - methodB序列之间的可见性,那么它就OK - AtomicBoolean就足够了。

答案 2 :(得分:0)

是。来自AtomicBoolean的Javadoc:

  

可以原子方式更新的{@code boolean}值。

这意味着对AtomicBoolean的任何更新都是不可分割的。所以,我会考虑使用AtomicBoolean 线程安全

你仍然应该考虑宣布AtomicBoolean final:

private final AtomicBoolean running;