多线程newSingleThreadExecutor Starvation死锁

时间:2012-12-11 07:06:44

标签: java multithreading deadlock executors

这直接来自Java Concurrency in Practice。 以下导致死锁:

class ThreadDeadlock {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    public class RenderPageTask implements Callable<String> {
        public String call() throws Exception {
            Future<String> header, footer;
            System.out.println(Thread.currentThread().getName());
            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
            //System.out.println("executed header and footer");
            String headerS = header.get();
            System.out.println("retrieved header");
            String footerS = footer.get();
            return headerS+ footerS;
        }
    }
}



class LoadFileTask implements Callable<String>{
    String name;
    public LoadFileTask(String name) {
        super();
        this.name = name;
    }

    @Override
    public String call() throws Exception {
        /*Scanner s = new Scanner(name);
        StringBuilder str = new StringBuilder();
        while(s.hasNextLine()){
            str.append(s.nextLine());
        }*/
        System.out.println(Thread.currentThread().getName()+this.name);
        return "";
    }
}

/* Call from Main */
         private static void checkDeadLock(){
    ThreadDeadlock.RenderPageTask callable = new ThreadDeadlock().new RenderPageTask();
    ExecutorService es = Executors.newFixedThreadPool(1);
    es.submit(callable);
    es.shutdown();
}

我无法弄清楚为什么会导致死锁。 我已经检查了它确实。它甚至返回header.get()并打印检索到的标题,然后它是如何死锁的?

2 个答案:

答案 0 :(得分:2)

您的代码中没有死锁,JVM没有关闭,因为它有exec服务的工作线程 - 执行程序线程(在ThreadDeadlock中定义)。 如果你添加

exec.shutdown();
return RenderPageTask之前

,程序将在所有任务完成后终止。

答案 1 :(得分:0)

死锁原因很简单:第一个任务提交另外两个任务并等待它们完成,有效地阻塞执行程序的单个工作线程并阻止执行任务。

或者:

  • 不要在执行程序

  • 下运行的任务中使用阻塞操作
  • 或使用执行者根据需要添加工作线程