So I have stripped down the someMethod() to just latch.await() and the retrieveValue() call. Validation gives me the hint to 'call countDown on the object stored in the latch field'. But why?
await stops all threads till the latchs internal counter is set to zero. If I countdown before await what's the sense of await? And if I add it later it has no sense either cause all threads stop at the await position and never will reach countDown except I countDown somewhere else like in main. Here I created a task that just calls someMethod and then I call countDown. That's how I understand it should be working.
So why calling countdown in someMethod?
package com.codegym.task.task27.task2711;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/*
CountDownLatch
*/
public class Solution {
//private final Object lock = new Object();
//private volatile boolean isWaitingForValue = true;
CountDownLatch latch = new CountDownLatch(1);
/*
//someMethod original
public void someMethod() throws InterruptedException {
synchronized (lock) {
while (isWaitingForValue) {
lock.wait();
}
retrieveValue();
isWaitingForValue = false;
lock.notify();
}
}
*/
//someMethod using latch
public void someMethod() throws InterruptedException {
latch.await();
retrieveValue();
}
void retrieveValue() {
System.out.println("Value retrieved.");
}
public static void main(String[] args) {
//create a Solution object
Solution s = new Solution();
//create a thread and run it that just calls someMethod (to get the Value)
new Thread(() -> {
try {
s.someMethod();
} catch (InterruptedException ignore) {}
}).start();
//wait a little bit (2 secs)
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException ignore) {}
//that's when using the latch
s.latch.countDown();
//that would be necessary to get the value when using the original code
/*
s.isWaitingForValue = false;
System.out.println("set isWaitingForValue = false");
synchronized (s.lock) {
s.lock.notifyAll();
}
System.out.println("notify");
*/
}
}