简体   繁体   中英

Synchronization with volatile 'status flag' boolean?

I've read about the 'status flag' pattern for the volatile usage. It says that I can use the volatile without any sync if the status flag doesn't depend on any other state. It will guarantee the visibility of the flag for other threads. Moreover, write to the boolean is atomic.

But in the other related question it's said that it's safe to use the volotile when only one thread can modify the flag. Otherwise, I need to use any synchronization or AtomicBoolean .

In my example, I have the stopped flag, but it could be modified more than from within one thread: methods stop() and continue() . The doSmth() doesn't update any states. If assume that it's OK not to do work when the stop() was invoked right after the continue() method, would be the code threadsafe?

class MyClass {
    private volatile boolean stopped;

    public void doWork() {
        while(!stopped) {
            doSmth();
        }
    }

    public void stop() {
        stopped = true;
    }

    public void continue() {
        stopped = false;
    }
}

As for me, it should. Could you please clarify if I'm wrong?

volatile simply ensures that changes to the variable are available to all threads.

The background: a thread may make local copies of shared variables. Synchronizing the values of these local variables with the global shared variables is what volatile effects.

However that does not synchronize in the java sence of a single entry, monitor/critical region.

The entire toolchest of java.util.concurrent offers things like ensuring that only one thread may change the value and such. If you want to start from ground up, one can with two variables do some blocking things: search for Dijkstra algorithms .

Here I think AtomicBoolean might be nice for non-blocking usage.


If you want to achieve to have a global boolean state that pauses resp. resumes threads when toggled (your stopped ), instead of some ugly busy wait :

public void run () {
    while (true) {
        doWork(); 
        try {
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException ex) {
            return;
        }
    }
}

Using a global CyclicBarrier - not the nicest API as it works with N predefined Runnable s.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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