//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
开始RenderPageTask
在单独的Thread
,唯一的Thread
,将提交执行其他任务exec
顺序。call()
将RenderPageTask
另外两个任务的内部方法提交给exec
。第一是LoadFileTask("header.html")
,第二是LoadFileTask("footer.html")
。但是由于exec
通过此处Executors.newSingleThreadExecutor();
提到的代码获得的ExecutorService 使用了一个单一的工作线程,该工作线程在一个无限制的queueThread上运行,* 并且该线程已经被分配给RenderPageTask,因此, 它将被排队进入无限制的队列,等待那个线程的执行。 *LoadFileTask("header.html")``LoadFileTask("footer.html")``Thread
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单例模式、饥饿模式代码实例的使用技巧和注意事项,需要的朋友参考一下