我有以下Runnable.run()方法:
public void run() {
calculateStuff();
boolean ioSuccesful = IOforThisRunnable();
while(!ioSuccesful ) {
Thread.sleep(500); // alternative?
boolean ioSuccesful = IOforThisRunnable();
}
}
我想在具有最大线程数的ThreadPoolExecutor中执行此代码。
现在我的问题:
假设我的线程池包含5个线程。在当前示例中,5个runnables将阻止执行任何其他线程,因为Thread.sleep()不会释放线程?! (如果IO不成功)
有没有办法释放线程而不是使用Thread.sleep(),以便其他runnable可以开始执行而另一个正在等待IO?
那么在最坏的情况下,所有runnable都会坐在while循环中?
答案 0 :(得分:2)
如果您的I / O工作正在阻塞,那么您别无选择:线程必须位于堆栈上,等待阻塞I / O完成,以便该线程无法执行任何其他工作。
你想要的是使用非阻塞I / O,结合Guava的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);
}