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,则应确保线程池的容量足以以所需的并行度执行它们。

10-06 01:27