我有以下 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,结合类似的东西 番石榴的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);
}