当前位置: 首页 > 面试题库 >

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

高展
2023-03-14
问题内容
//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开始RenderPageTask在单独的Thread,唯一的Thread,将提交执行其他任务exec顺序。
  3. call()RenderPageTask另外两个任务的内部方法提交给exec。第一是LoadFileTask("header.html"),第二是LoadFileTask("footer.html")。但是由于exec通过此处Executors.newSingleThreadExecutor();提到的代码获得的ExecutorService 使用了一个单一的工作线程,该工作线程在一个无限制的queueThread上运行,* 并且该线程已经被分配给RenderPageTask,因此, 它将被排队进入无限制的队列,等待那个线程的执行。 *LoadFileTask("header.html")``LoadFileTask("footer.html")``Thread
  4. RenderPageTask正在返回一个字符串,其中包含输出LoadFileTask("header.html"),页面主体和输出的串联 LoadFileTask("footer.html")。这三个部分page中的成功通过即可获得RenderPageTask。但是其他两个部分只能在由分配的单个线程执行两个任务之后获得ExecutorService。并且Thread仅在call()return方法之后才可用RenderPageTask。但是的call方法RenderPageTask仅在LoadFileTask("header.html")LoadFileTask("footer.html")返回之后才返回。因此,不让LoadFileTask执行就导致 饥饿 。每个等待其他任务完成的任务都会导致 死锁,

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



 类似资料:
  • 主要内容:死锁,活锁,饥饿,总结本节我们来介绍一下死锁、活锁和饥饿这三个概念。 死锁 死锁是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 死锁发生的条件有如下几种: 1) 互斥条件 线程对资源的访问是排他性的,如果一个线程对占用了某资源,那么其他线程必须处于等待状态,直到该资源

  • 问题内容: 我找到了一段似乎线程饥饿的代码。下面是一个简化的示例。这是饥饿的例子吗?线程不终止的原因是什么? 注意:将睡眠更改为1有时会导致终止。注释掉的Thread.yield()将解决问题(对我来说)。 问题答案: 您可能需要了解Java内存模型。多线程不仅涉及 交织 线程的行为,还涉及多线程。它是关于一个线程到另一个线程的动作 可见性 。 这个问题的根本在于面对并发性时需要进行积极的优化:确

  • 我对和使用了RXJava。我知道他们不是在一条流上并行化排放。换句话说,单个排放流只会放在一个线程上,对吗?我下面的测试似乎表明了这一点。我的理解是,您还必须调度器,如,以在单个流上并行化发射。 同样,如果是这种情况,那么调度器会发生线程饥饿吗?如果我的计算调度程序有5个线程,但我有超过5个长时间运行的异步流正在处理,有没有可能出现饥饿?或者这不太可能仅仅是因为RXJava的性质?

  • 这是Geeksforgeeks使用信号量解决用餐哲学家问题的方法: https://www.geeksforgeeks.org/dining-philosopher-problem-using-semaphores/ 这个代码死锁活锁和饥饿的概率很低,我想改变它,它将有死锁,活锁或饥饿的概率很高,我怎么做? 此外,我如何确保这个解决方案不会有任何这些问题100%(如果可能的话)

  • 我试图使一个插件,消除饥饿从我的世界。但是,我找不到它的事件! 有没有一个叫玩家失去饥饿感的活动? 像?

  • 本文向大家介绍Java单例模式、饥饿模式代码实例,包括了Java单例模式、饥饿模式代码实例的使用技巧和注意事项,需要的朋友参考一下