سؤال

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?

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top