假设我们有n个线程访问此函数,我听说即使布尔值只是一些翻转,该过程也不是原子的。在此功能中,opening = true是否需要包装在同步中? opening是该类的成员。

boolean opening = false;

public void open() {

    synchronized (this) {
        while (numCarsOnBridge != 0 || opening || closing) {
            // Wait if cars on bridge, opening or closing
            try {
                // Wait until all cars have cleared the bridge, until bridge opening
                wait();
            } catch (InterruptedException e) {}
        }
        // By now, no cars will be under the bridge.
    }

    if (!opening) {
        opening = true; // Do we need to wrap this in a synchronize?
        // notifyAll(); // Maybe need to notify everyone that it is opening
        try {
            sleep(60); // pauses the current thread calling this
        } catch (InterruptedException e) {}

        synchronized (this) {
            drawBridgeClosed = false; // drawBridge is opened
            opening = false;
            notifyAll(); // Only notify all when state has fully changed
        }
    }

}

最佳答案

是的,对布尔值的并发修改需要同步,请使用AtomicBoolean或同步的构造。

另外,如果不在此处拥有监视器,就无法调用notifyAll():

if (!opening) {
    opening = true; // Do we need to wrap this in a synchronize?
    // notifyAll(); // Maybe need to notify everyone that it is opening


因此,您已经有两个理由将其包装在同步块中。

10-07 15:21