Here is a scenario, when the output I am expecting from below code is
First Function
Second Function
Main Execution Completed!
But the problem here is the run method that prints "Second Function" is never getting the value of volatile flag to true to print "Second Function" and call countDown on countdownlatch object. Hence the countdownlatch.await() keeps waiting without any outcome. Is there any other approach to execute the respective run methods in a particular sequence? I understand this defeats the purpose of asynchronous programming in java, but if at all its possible kindly let me know.
public class Application {
private static CountDownLatch countDownLatch = new CountDownLatch(2);
public static void executeAndWait(List<Runnable> runnables) {
runnables.forEach(r -> new Thread(r).start());
}
public static void main(String[] args) throws InterruptedException {
List<Runnable> runnables = Arrays.asList(() -> {
try {
while(flag) {
Thread.sleep(100);
System.out.println("Second Function");
countDownLatch.countDown();
break;
}
} catch(Exception e) {}
}, () -> {
try {
Thread.sleep(100);
System.out.println("First Function");
flag = true;
countDownLatch.countDown();
} catch(Exception e) {}
});
executeAndWait(runnables);
countDownLatch.await();
System.out.println("Main Execution Completed!");
}
}
Core problem here is that when the second thread reaches the condition guarding the
whileloop:flagmay be eithertrueoffalse. Ifflagisfalsethen the whole loop is skipped, and the execution of that thread terminates.What we actually want is an endless loop, with a condition that
when
flagistrue.Hence, we can rewrite the
Runnable:ideone.comdemoA remark on the code: We can and should move the
try { ... } catch (...) { ... }as close to theThread.sleep(...)as possible. Hence, I propose the following structual change: