为什么会陷入僵局

时间:2010-10-12 18:01:49

标签: java concurrency deadlock

“实践中的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}}

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提交相互依赖的任务,则应确保线程池的容量足以以所需的并行级别执行它们。