“实践中的Java并发”清单8.1中的代码
为什么代码会死锁?是因为rpt.call
中的main()
与Executors中的exec = Executors.newFixedThreadPool(10);
基本相同吗?
即使我为public class ThreadDeadlock {
ExecutorService exec = Executors.newSingleThreadExecutor();
public class RenderPageTask implements Callable<String> {
public String call() throws Exception {
Future<String> header, footer;
header = exec.submit(new LoadFileTask("header.html"));
footer = exec.submit(new LoadFileTask("footer.html"));
String page = renderBody();
// Will deadlock -- task waiting for result of subtask
return header.get() + page + footer.get();
}
}
public static void main(String [] args ) throws Exception {
ThreadDeadlock td = new ThreadDeadlock();
ThreadDeadlock.RenderPageTask rpt = td.new RenderPageTask();
rpt.call();
}
}
使用了10个线程,它仍然会死锁?
{{1}}
答案 0 :(得分:9)
您的代码没有死锁 - 以下内容:
public class ThreadDeadlock {
...
public static void main(String [] args ) throws Exception {
ThreadDeadlock td = new ThreadDeadlock();
ThreadDeadlock.RenderPageTask rpt = td.new RenderPageTask();
Future<String> f = td.exec.submit(rpt);
System.out.println(f.get());
td.exec.shutdown();
}
}
如果您在单个线程执行程序中同时提交多个任务,而第一个任务正在等待以下任务的结果,则会发生这种情况。它不会与Executors.newFixedThreadPool(2)
发生死锁,因为LoadFileTask
是独立的,当RenderPageTask
使用另一个线程时,它可以共享一个线程。
此示例的要点是,如果您向ExecutorService
提交相互依赖的任务,则应确保线程池的容量足以以所需的并行级别执行它们。