CountDownLatch.await()挂断
CountDownLatch.await() hangs up
谁能解释为什么 CountDownLatch
方法等待挂起,尽管我在单独的线程中执行 countDown?这个测试永远不会结束,有趣的是 ThreadPoolTaskExecutor
没有在我想执行 countDown 方法的地方执行代码。我确定 ThreadPoolTaskExecutor
在不同的线程中执行回调并且 CountDownLatch::await
将被释放。
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; }
}
如果我在 await 方法中设置任何超时,任务执行器中的回调将在超时后执行并测试通过...我无法理解这一点..
问题出在池的大小上。默认情况下 ThreadPoolTaskExecutor 在池中只有一个线程。我增加了 corePolSize,现在他的代码可以工作了。谢谢安德烈亚斯!
谁能解释为什么 CountDownLatch
方法等待挂起,尽管我在单独的线程中执行 countDown?这个测试永远不会结束,有趣的是 ThreadPoolTaskExecutor
没有在我想执行 countDown 方法的地方执行代码。我确定 ThreadPoolTaskExecutor
在不同的线程中执行回调并且 CountDownLatch::await
将被释放。
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; }
}
如果我在 await 方法中设置任何超时,任务执行器中的回调将在超时后执行并测试通过...我无法理解这一点..
问题出在池的大小上。默认情况下 ThreadPoolTaskExecutor 在池中只有一个线程。我增加了 corePolSize,现在他的代码可以工作了。谢谢安德烈亚斯!