Skip to content
Advertisement

Using volatile for skipping method execution

I’ve never used volatile very often. Is it possible to use it to skip method execution if another thread executing it? I think in the code below it’s still possible that multiple threads pass the check and execute the method. Isn’t it?

private static boolean volatile test = false;
...
    public void test() {
        if (test) {
            return;
        }
        test = true;
        try {
            System.out.println("test() started in Thread with ID " + Thread.currentThread().getId());
            Thread.sleep(10000);
            System.out.println("test() finished in Thread with ID " + Thread.currentThread().getId());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        test = false;
    }

Use case: The method can be run periodically but at the same time it can be triggered manually by a user. There is no reason to run it twice one after another by using synchronized keyword. Please, tell me it’s doable with volatile. Otherwise I don’t see any reason to understand it except for job interviews 🙂 Other solutions that aren’t based on volatile are welcome.

Advertisement

Answer

You can use a volatile AtomicBoolean, like this, to achieve your requirement.

// default false so that first-thread that test() can enter the logic block
// AtomicBoolean's value is inherently volatile, so no need to declare volatile here
private static final AtomicBoolean test = new AtomicBoolean(false);   


public void test() {
    if (test.compareAndSet(false, true)) {  // check if the test if previously false and if so update it to true
        try {
            System.out.println("test() started in Thread with ID " + Thread.currentThread().getId());
            Thread.sleep(10000);
            System.out.println("test() finished in Thread with ID " + Thread.currentThread().getId());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            test.set(false); // executing thread now re-sets the test value
        }
    }
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement