Java ThreadPoolExecutor 将线程释放到线程池



我有以下 Runnable.run() 方法:

public void run() {
    calculateStuff();
    boolean ioSuccesful = IOforThisRunnable();   
    while(!ioSuccesful ) {
        Thread.sleep(500);   // alternative?
        boolean ioSuccesful = IOforThisRunnable();
    }  
}

我想在具有最大线程数的 ThreadPoolExecutor 中执行此代码。

现在回答我的问题:

假设我的线程池由 5 个线程组成。在当前示例中,5 个可运行对象将阻止任何其他线程的执行,因为 Thread.sleep() 不会释放线程?!(如果 IO 不成功)

有没有办法释放线程而不是使用 Thread.sleep(),以便其他可运行对象可以在另一个正在运行的等待 IO 时开始执行?

因此,在最坏的情况下,所有可运行的变量都会坐在 while 循环中?

如果您的 I/O 工作阻塞,

那么您别无选择:线程必须坐在堆栈上等待阻塞 I/O 完成,以便线程不能执行任何其他工作。

你想要的是使用非阻塞I/O,结合类似的东西 番石榴的ListenableFuture .这将使您能够执行以下操作:

static ListenableFuture<Boolean> doIoWork() {
  // ...
}
static ListenableFuture<Boolean> doIoWithRetry(
    ListeningExecutorService executor) {
  SettableFuture<Boolean> finalResult = SettableFuture.create();
  calculateStuff();
  doIoWithRetry(executor, finalResult);
  return finalResult;
}
private static void doIoWithRetry(
    final ListeningExecutorService executor,
    final SettableFuture<Boolean> finalResult) {
  final ListenableFuture<Boolean> pendingWork = doIoWork();
  pendingWork.addListener(new Runnable() {
    @Override public void run() {
      // pendingWork is now complete
      // (error checking elided here)
      boolean ioSuccessful = pendingWork.get();
      if (ioSuccessful) {
        finalResult.set(true);
        return;
      }
      doIoWithRetry(executor, finalWork);
    }
  }, executor);
}

最新更新