java - 代码中是否发生了线程饥饿死锁?

标签 java concurrency deadlock executorservice

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

导致死锁的步骤:

  1. 任务提交给 exec 以通过 Callable 实现的类 RenderPageTask 呈现页面。
  2. exec 在单独的 Thread 中启动了 RenderPageTask ,唯一的 Thread 会执行提交给 exec顺序。
  3. RenderPageTaskcall() 方法中,另外两个任务被提交给 exec 。第一个是 LoadFileTask("header.html"),第二个是 LoadFileTask("footer.html")。但是由于 ExecutorService exec 通过代码 Executors.newSingleThreadExecutor(); 获得,如前所述 here 使用单个工作线程在无界 queueThread 上运行,并且该线程已分配给 RenderPageTask,因此 LoadFileTask("header.html")LoadFileTask("footer .html") 将被排入无界队列,等待轮到该 Thread 执行。
  4. RenderPageTask 正在返回一个字符串,其中包含 LoadFileTask("header.html") 输出、页面正文和 LoadFileTask("footer .html")RenderPageTask 成功获取了这三部分 page 。而其他两部分只有在ExecutorService分配的单个Thread执行完两个任务后才能获取。只有在RenderPageTaskcall()方法返回后Thread才会空闲。但是 RenderPageTaskcall 方法只会在 LoadFileTask("header.html")LoadFileTask("footer.html") 之后返回 被返回。所以不让 LoadFileTask 执行会导致 Starvation 。每个等待其他任务完成的任务都会导致死锁

    我希望这能弄清楚为什么在上面的代码中会发生线程饥饿死锁。

关于java - 代码中是否发生了线程饥饿死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14661036/

相关文章:

java - 获取所有属性是否会在幕后进行左连接?

Java 互斥锁与 smp

c# - 如何摆脱 SQL Server 2005 和 C# 应用程序中的死锁?

c++ - 是否可以使用互斥锁来锁定 vector 中的元素而不是整个 vector ?

java - 适用于 Windows 的 JDK/JRE 安装

java - 是否使用了 switch 语句中的所有情况...?

java - 将 http 更改为 https

java - 使用汇率转换货币

WCF 并发连接和 Azure 服务总线中继

sql-server-2005 - Sql Server 2005 : deadlock problem with no shared records