Could anyone explain me why CountDownLatch
on method await is hanging up although I execute countDown in separated thread? This test never ends and what is interesting ThreadPoolTaskExecutor
doesn't execute code where I want to execute countDown method. I was sure that ThreadPoolTaskExecutor
executes callback in different thread and CountDownLatch::await
will be released.
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
...
private ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
@Test
void nestedInitialization() {
executor.initialize();
var beanInitializer = new Initializer(executor);
beanInitializer.initialize(() -> {
new SomeBean().init();
});
sleep(150);
assertEquals(0, executor.getThreadPoolExecutor().getQueue().size());
assertTrue(beanInitializer.isInitializationDone());
}
class SomeBean {
private AnotherBean anotherBean = new AnotherBean();
void init() {
anotherBean.init();
}
}
class AnotherBean {
private final Initializer initializer = new Initializer(executor);
void init() {
initializer.initialize(this::internalInit);
}
void internalInit() {
sleep(100);
}
}
public class Initializer {
private ThreadPoolTaskExecutor bootstrapExecutor;
private final CountDownLatch countDownLatch = new CountDownLatch(2);
private Initializer(ThreadPoolTaskExecutor bootstrapExecutor) {
this.bootstrapExecutor = bootstrapExecutor;
}
public void initialize(Runnable callback) {
synchronized (this) {
if (isNotInitialized()) {
countDownLatch.countDown(); // set 1 in latch
bootstrapExecutor.execute(() -> {
callback.run();
countDownLatch.countDown(); // <-- this doesn't execute
});
}
}
if (initializationStarted()) {
try {
countDownLatch.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
boolean isNotInitialized() { return countDownLatch.getCount() == 2; }
boolean initializationStarted() { return countDownLatch.getCount() == 1; }
boolean isInitializationDone() { return countDownLatch.getCount() == 0; }
}
If I set any timeout in await method, callback in task executor will be executed after timeout and test passed...I can't understand this..
Problem was with size of pool. In default ThreadPoolTaskExecutor has only one thread in pool. I increased corePolSize and now his code works. Thanks Andreas!