Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Block and wait using AtomicBoolean

I am looking for a way of pausing a Thread.

I started with affectively using a boolean flag (called 'paused'), and wrapping a check with a while loop (pause).

Within the while loop there’s a Thread.wait() to block the execution.

I’ve been looking at the AtomicBoolean, which seems to do the trick apart from it doesn’t block.

Is there a alternative or extended version of AtomicBoolean that has a block method ?

i.e. something like AtomicBoolean.getFalse() of AtomoicBoolean.get(false)?

They have a Blocking Queue, so a Blocking value.

Current setup is :

while (paused.get()) {
        synchronized (paused) {
            try {

                paused.wait();
            } catch (Exception e) {
            }

            paused.notify();
        }
    }

with

public void pause() {
    if (paused.compareAndSet(false, true)) {
        synchronized (paused) {
            paused.notify();
        }
    }

}


public void resume() {
    if (paused.compareAndSet(true, false)) {
        synchronized (paused) {
            paused.notify();
        }
    } 
}
like image 610
Ben Avatar asked Nov 21 '11 14:11

Ben


People also ask

What is the use of AtomicBoolean?

AtomicBoolean class provides operations on underlying boolean value that can be read and written atomically, and also contains advanced atomic operations. AtomicBoolean supports atomic operations on underlying boolean variable. It have get and set methods that work like reads and writes on volatile variables.

Is AtomicBoolean thread safe?

7. Atomic Objects. It's also possible to achieve thread-safety using the set of atomic classes that Java provides, including AtomicInteger, AtomicLong, AtomicBoolean and AtomicReference. Atomic classes allow us to perform atomic operations, which are thread-safe, without using synchronization.

What is difference between boolean and AtomicBoolean in Java?

AtomicBoolean has methods that perform their compound operations atomically and without having to use a synchronized block. On the other hand, volatile boolean can only perform compound operations if done so within a synchronized block.

What is atomic boolean in Android?

A boolean value that may be updated atomically. See the VarHandle specification for descriptions of the properties of atomic accesses. An AtomicBoolean is used in applications such as atomically updated flags, and cannot be used as a replacement for a Boolean .


2 Answers

    AtomicBoolean lock = new AtomicBoolean(false);
    if(lock.compareAndSet(false, true)){
        try {
            //do something
        } catch(Exception e){
            //error handling
        } finally {
            lock.set(false);
        }
    }

First, unless you use an atomic operation (something like test-and-set), AtomicBoolean is as useless as a regular Boolean (If they were mutable). Here I'm using compareAndSet, so that it only enters the critical section if the flag was down. Remember to always unlock in finally.

To pause a thread using a flag, don't go for active wait (some loop in thread body asking "Am I paused?"), as it is not an efficient practice. I'd use a wait-notify scheme. When the thread has no more work to do, it calls wait on some object. Then, to restart, some other thread calls notify on that same object.

If you want to immediately pause (in terms of skip execution when the flag is set), you could divide the code in as much steps as possible, and wrap each one with a test, to finally wait if paused:

public void run(){
    while(true){
        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(paused){
            //wait on some object
        }
    }       
}   

Depending of your code, the steps may be even nested, or include undivisible units of execution involving several steps.

like image 53
Mister Smith Avatar answered Oct 22 '22 16:10

Mister Smith


Use a CountDownLatch of 1:

CountDownLatch conditionLatch = new CountDownLatch(1);

In the place you want to wait for some condition to become true:

conditionLatch.await();

In the place you want to set the condition to true:

conditionLatch.countDown();
like image 36
qwertzguy Avatar answered Oct 22 '22 16:10

qwertzguy