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

huangapple go评论74阅读模式
英文:

What's the inter-thread communication mechanism that can await and release underlying thread resource at the same time

问题

我正在寻找一种可以同时等待和释放底层线程资源的线程间通信机制。在我的下面的示例中,当executorService只使用1个线程进行初始化时,第二个任务将会被阻塞,因为线程被t1占用,即使它在等待。只有当您将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个线程时的输出。

start t1
Master thread ends

executorService初始化为2个线程时的输出。

start t1
Master thread ends
start t2
t2 done
t1 done

理想情况下,当t1等待时,它不需要持有底层线程,以便任务2可以在此线程池内运行。这个问题的一个现实用例是,如果我有一个线程池,并且任务将被提交/调度回同一个池进行重试。从理论上讲,当所有提交的任务立即失败时,由于没有线程来运行重试任务,该过程将会被阻塞。

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

英文:

I am looking for an inter-thread communication mechanism that can await and release underlying thread resource at the same time. In my example below, when the executorService is initialized with only 1 thread, the second task will be stuck because the thread is held by t1 even though it's await. The code below will only work if you change to initialize the executorService with 2 threads.

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");
}

The output when executorService is initialized with 1 thread.

start t1
Master thread ends

The output when executorService is initialized with 2 threads.

start t1
Master thread ends
start t2
t2 done
t1 done

Ideally, when t1 is waiting, it doesn't need to hold the underlying thread such that task2 can run within this thread pool. A real-world use case of this problem is that if I have a thread pool, and the tasks will be submitted/scheduled back to the same pool for retries. Theoretically, the process will be stuck when all tasks submitted failed immediately because there are no threads for running the retry tasks.

Creating a separate thread pool for retry can solve this problem, but I am wondering if JAVA provides an inter-thread communication mechanism that allows waiting and releasing the underlying thread at the same time, so that only 1 thread pool is needed.

答案1

得分: 0

The only way to release underlying thread resource is to completely return from the main method of the task (usually Runnable::run). To await at the same time, the event producer should be subscribed in asynchronous way. Not every producer has asynchronous interface. CompletableFuture has (method whenComplete), but CountDownLatch has not. However, you can extend CountDownLatch with asynchronous functionality, subscribe to its completion, return from run() and wait. I did so in my DF4J library: AsyncCountDownLatch.java

英文:

The only way to release underlying thread resource is to completely return from the main method of the task (usually Runnable::run). To await at the same time, the event producer should be subscribed in asynchronous way. Not every producer has asynchronous interface. CompletbleFuture has (method whenComplete), but CountDownLatch has not. However, you can extend CountDownLatch with asynchronous finctionality, subscribe to its completion, return from run() and wait. I did so in my DF4J library: AsyncCountDownLatch.java

huangapple
  • 本文由 发表于 2020年8月2日 05:07:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63210084.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定