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 } } }