目前我一直使用FixedThreadPool
来细分大型任务;这一切都很好。然而;我现在发现其中一个任务的一部分本身可以细分。我曾尝试向FixedThreadPool
提交更多Callables,但程序挂在Future#get()
上(在代码中标明)
以下程序复制了问题(我使用了大小为1的FixedThreadPool
来加剧问题)
public class ThreadPoolTest {
static ExecutorService threadPool=Executors.newFixedThreadPool(1);
//method run by inner callable
public void printText(){
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ThreadPoolTest.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Printed from within thread");
}
//method run by outer callable
public void testThreadPool(){
Callable<Void> printOnAThread=()->{printText(); return null; };
Future<Void> f2=threadPool.submit(printOnAThread);
try {
System.out.println("Called");
f2.get(); //<--hangs here
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(ThreadPoolTest.class.getName()).log(Level.SEVERE, null, ex);
throw new RuntimeException("Failed to print in thread", ex);
}
}
public static void testThreadWithinThread(){
ThreadPoolTest t=new ThreadPoolTest();
Callable<Void> testCallable=()->{t.testThreadPool();return null;};
Future<Void> f=threadPool.submit(
testCallable
);
try {
f.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(ThreadPoolTest.class.getName()).log(Level.SEVERE, null, ex);
throw new RuntimeException("Main thread failed", ex);
}
}
public static void main(String[] args){
testThreadWithinThread();
threadPool.shutdown();
System.out.println("Program exits");
}
}
testThreadWithinThread()
运行testThreadWithinThread()
提交Callable(()->{t.testThreadPool();return null;};
)testThreadPool();
本身提交内部可调用()->{printText(); return null; };
f.get();
,外部可调用块并等待。这将释放FixedThreadPool
f2.get();
不再被阻止,外部可调用运行完成步骤1-6按照我的预期发生,但在第7点时外部可调用被阻止;由于某种原因,它不会释放线程,因此程序会挂起。
为什么程序在此时挂起?有什么方法可以安全地从callables中提交callables吗?
答案 0 :(得分:2)
您的线程池包含1个线程。它一次只能执行一个可调用/可运行。所有其他提交的任务都排队,直到有一个线程可以执行它们。
增加游泳池大小。