Question

This is straight from Java Concurrency in Practice. The following causes a Deadlock :

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();
}

I am unable to figure out why this causes a deadlock. I have checked and it does.It even returns the header.get() and prints retrieved header, then how does it deadlock?

Était-ce utile?

La solution

There is no deadlock in your code, JVM doesn't shutdowned because it have working thread - executor thread for exec service(defined in ThreadDeadlock). If you add

exec.shutdown();

before return in RenderPageTask then program will terminate after all tasks will be completed.

Autres conseils

The deadlock cause is simple: the first task submits another 2 tasks and waits them to finish, effectively blocking the single working thread of the executor and preventing that tasks from execution.

Either:

  • do not ever use blocking operations in the tasks running under executor

  • or use executor which adds working threads as needed

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top