//code taken from java concurrency in practice
package net.jcip.examples;
import java.util.concurrent.*;
public class ThreadDeadlock
{
ExecutorService exec = Executors.newSingleThreadExecutor();
public class LoadFileTask implements Callable<String> {
private final String fileName;
public LoadFileTask(String fileName) {
this.fileName = fileName;
}
public String call() throws Exception {
// Here's where we would actually read the file
return "";
}
}
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();
}
}
}
这段代码取自 Java 并发实践,根据作者的说法,“ThreadStarvtionDeadlock”正在这里发生。请帮我找出 ThreadStarvationDeadlock 是如何发生在这里和哪里的?提前致谢。
最佳答案
死锁和饥饿发生在以下行:
return header.get() + page + footer.get();
怎么做?
如果我们在程序中添加一些额外的代码,就会发生这种情况。可能是这个:
public void startThreadDeadlock() throws Exception
{
Future <String> wholePage = exec.submit(new RenderPageTask());
System.out.println("Content of whole page is " + wholePage.get());
}
public static void main(String[] st)throws Exception
{
ThreadDeadLock tdl = new ThreadDeadLock();
tdl.startThreadDeadLock();
}
导致死锁的步骤:
- 任务提交给
exec
以通过Callable
实现的类RenderPageTask
呈现页面。 exec
在单独的Thread
中启动了RenderPageTask
,唯一的Thread
会执行提交给exec
顺序。- 在
RenderPageTask
的call()
方法中,另外两个任务被提交给exec
。第一个是LoadFileTask("header.html")
,第二个是LoadFileTask("footer.html")
。但是由于 ExecutorServiceexec
通过代码Executors.newSingleThreadExecutor();
获得,如前所述 here 使用单个工作线程在无界 queueThread 上运行,并且该线程已分配给 RenderPageTask,因此LoadFileTask("header.html")
和LoadFileTask("footer .html")
将被排入无界队列,等待轮到该Thread
执行。 RenderPageTask
正在返回一个字符串,其中包含LoadFileTask("header.html")
输出、页面正文和LoadFileTask("footer .html")
。RenderPageTask
成功获取了这三部分page
。而其他两部分只有在ExecutorService
分配的单个Thread执行完两个任务后才能获取。只有在RenderPageTask
的call()
方法返回后Thread才会空闲。但是RenderPageTask
的call
方法只会在LoadFileTask("header.html")
和LoadFileTask("footer.html") 之后返回
被返回。所以不让LoadFileTask
执行会导致 Starvation 。每个等待其他任务完成的任务都会导致死锁
我希望这能弄清楚为什么在上面的代码中会发生线程饥饿死锁。
关于java - 代码中是否发生了线程饥饿死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14661036/