线程饥饿死锁在代码中发生了吗? [英] Is thread starvation deadlock happening here in the code?

查看:160
本文介绍了线程饥饿死锁在代码中发生了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

//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如何发生这里和哪里?先感谢。

This code is take from Java concurrency in practice and as per the authors "ThreadStarvtionDeadlock" is happening here. Please help me finding how ThreadStarvationDeadlock is happening here and where? Thanks in advance.

推荐答案

Deadlock&饥饿发生在以下行:

Deadlock & Starvation is occurring at following line:

return header.get() + page + footer.get();

如何?

向程序添加一些额外的代码。可能是这个:

HOW?
It will happen if we add some extra code to the program. It might be this one:

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

导致deadLock的步骤:

Steps that leading to deadLock:


  1. 任务提交到 exec ,用于通过 Callable RenderPageTask c> c> c> 在单独的线程中,将执行提交到<$ c的其他任务的唯一线程 c> c> c> c> 两个任务提交到 exec 。首先是 LoadFileTask(header.html),第二个是 LoadFileTask(footer.html)。但是因为ExecutorService exec 通过代码 Executors.newSingleThreadExecutor(); 获得在这里 使用单个工作线程关闭一个无界的queueThread ,并且线程已经分配给RenderPageTask,所以 LoadFileTask(header.html) LoadFileTask html)将被排队到无界队列,等待由线程执行。

  2. RenderPageTask 正在返回一个字符串,其中包含 LoadFileTask(header.html) LoadFileTask(footer.html)的输出。在这三个部分中, RenderPageTask 成功获得了。但是其他两个部分只有在两个任务都由由 ExecutorService 分配的单个线程执行之后才能获得。只有 call()方法 RenderPageTask 返回时,线程才会自由。但调用方法 RenderPageTask 只会在后返回LoadFileTask(header.html)返回LoadFileTask(footer.html)。因此,不要让执行 LoadFileTask 导致 Starvation 。每个任务等待其他任务完成导致 DeadLock



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

  1. Task is submitted to exec for Rendering the page via Callable implemented class RenderPageTask.
  2. exec started the RenderPageTask in separate Thread , the only Thread that would execute other tasks submitted to exec sequentially .
  3. Inside call() method of RenderPageTask two more tasks are submitted to exec . First is LoadFileTask("header.html") and second is LoadFileTask("footer.html"). But since the the ExecutorService exec obtained via code Executors.newSingleThreadExecutor(); as mentioned here uses a single worker thread operating off an unbounded queueThread and the thread is already allocated to RenderPageTask , So LoadFileTask("header.html") and LoadFileTask("footer.html") will be en queued to the unbounded queue waiting for there turn to be executed by that Thread.
  4. RenderPageTask is returning a String containing the concatenation of output of LoadFileTask("header.html") , body of page and output of LoadFileTask("footer.html"). Out of these three parts page is obtained successfully by RenderPageTask . But other two parts can only be obtained after both tasks are executed by the single Thread allocated by ExecutorService . And Thread will be free only after call() method of RenderPageTask returns . But call method of RenderPageTask will return only after LoadFileTask("header.html") and LoadFileTask("footer.html") is returned. So Not letting LoadFileTask to execute is leading to Starvation . And each task waiting for other task for completion is leading to DeadLock

    I hope this makes clear of why thread starvation deadlock is occurring in above code.

这篇关于线程饥饿死锁在代码中发生了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆