list 8.1中的“Java并发实践”一书中的代码
为什么代码会死锁?是因为rpt.call
中的main()
与执行程序中的线程基本相同?
即使我为exec = Executors.newFixedThreadPool(10);
使用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();
}
}
最佳答案
您的代码不会死锁-以下代码会死锁:
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
,则应确保线程池的容量足以以所需的并行度执行它们。