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
execservice(defined inThreadDeadlock).If you add
before
returninRenderPageTaskthen program will terminate after all tasks will be completed.