首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是线程间的通信机制,可以同时等待和释放底层线程资源?

什么是线程间的通信机制,可以同时等待和释放底层线程资源?
EN

Stack Overflow用户
提问于 2020-08-01 21:07:28
回答 1查看 104关注 0票数 1

我正在寻找一个线程间的通信机制,可以等待和释放底层线程资源在同一时间。在下面的示例中,当仅用一个线程初始化executorService时,第二个任务将被卡住,因为线程被t1持有,即使它是await。下面的代码只有在您更改为用2个线程初始化executorService时才能工作。

代码语言:javascript
复制
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时的输出。

代码语言:javascript
复制
start t1
Master thread ends

用两个线程初始化executorService时的输出。

代码语言:javascript
复制
start t1
Master thread ends
start t2
t2 done
t1 done

理想情况下,当t1等待时,它不需要保存底层线程,这样task2就可以在这个线程池中运行。这个问题的一个真实的用例是,如果我有一个线程池,并且任务将被提交/调度回同一个池进行重试。理论上,当所有提交的任务都立即失败时,由于没有运行重试任务的线程,进程将被卡住。

为retry创建一个单独的线程池可以解决这个问题,但是我想知道JAVA是否提供了一种线程间通信机制,允许同时等待和释放底层线程,因此只需要一个线程池。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-02 15:19:35

释放底层线程资源的唯一方法是从任务的主要方法(通常是Runnable::run)完全返回。若要同时等待,应以异步方式订阅事件生成器。并不是每个生产者都有异步接口。CompletbleFuture有(whenComplete方法),但CountDownLatch没有。但是,您可以使用异步终结性扩展CountDownLatch,订阅它的完成,从run()返回和等待。我是在我的DF4J库中这样做的:AsyncCountDownLatch.java

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63210084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档