我正在寻找一种可以同时等待并释放底层线程资源的线程间通信机制。在下面的示例中,当executorService
仅使用1个线程初始化时,第二个任务将被卡住,因为该线程由t1保留,即使它是await
。以下代码仅在您更改为executorService
使用2个线程初始化时才有效。
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
CountDownLatch cdl = new CountDownLatch(1);
executorService.submit(() -> {
System.out.println("start t1");
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 done");
});
executorService.submit(() -> {
System.out.println("start t2");
cdl.countDown();
System.out.println("t2 done");
});
System.out.println("Master thread ends");
}
executorService
用1个线程初始化了when的输出。
start t1
Master thread ends
executorService
用2个线程初始化了when的输出。
start t1
Master thread ends
start t2
t2 done
t1 done
理想情况下,当t1等待时,它不需要保留基础线程,因此task2可以在此线程池中运行。这个问题在现实世界中的用例是,如果我有一个线程池,并且任务将被提交/安排回同一池中进行重试。从理论上讲,当所有提交的任务立即失败时,该进程将被阻塞,因为没有用于运行重试任务的线程。
创建一个单独的线程池进行重试可以解决此问题,但是我想知道JAVA是否提供了一种线程间通信机制,该机制允许同时等待和释放基础线程,因此仅需要一个线程池。
释放底层线程资源的唯一方法是完全从任务的主要方法(通常为Runnable :: run)返回。为了同时等待,事件生成器应该以异步方式进行订阅。并非每个生产者都有异步接口。CompletbleFuture有(Complete方法),但CountDownLatch没有。但是,您可以使用异步功能扩展CountDownLatch,订阅其完成,从run()返回并等待。我是在DF4J库中这样做的:AsyncCountDownLatch.java
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句