首页 > 其他分享 >线程饥饿死锁

线程饥饿死锁

时间:2022-12-07 17:00:28浏览次数:51  
标签:exec 饥饿 RenderPageTask 死锁 线程 任务 public


线程饥饿死锁:

      在一个线程池中,如果一个任务依赖于其他任务的执行,就可能产生死锁。对应一个单线程话的Executor,一个任务将另一个任务提交到相同的Executor中,并等待新提交的任务的结果,这总会引发死锁。第二个任务滞留在工作队列中,直到第一个任务完成,但是第一个任务不会完成,因为它在等待第二个任务的完成。

       同样在一个大的线程池中,如果所有线程执行的任务都阻塞在线程池中,等待着仍然处于同一个工作队列中的其他任务,那么会发生同样的问题。这就是线程饥饿死锁。



public class ThreadDeadlock {

ExecutorService exec = Executors.newSingleThreadScheduledExecutor();
// ExecutorService exec = Executors.newCachedThreadPool(); //如果添加给线程池中添加足够多的线程,就可以让所有任务都执行,避免饥饿死锁。

/**
* 模拟页面加载的例子
*
* 产生死锁分析:
* RenderPageTask任务中有2个子任务分别是“加载页眉”和“加载页脚”。当提交RenderPageTask任务时,实际上是向线程池中添加了3个任务,
* 但是由于线程池是单一线程池,同时只会执行一个任务,2个子任务就会在阻塞在线程池中。而RenderPageTask任务由于得不到返回,也会
* 一直堵塞,不会释放线程资源让子线程执行。这样就导致了线程饥饿死锁。
*
* 在一个Callable任务中,要返回2个子任务
* @author hadoop
*
*/
class RenderPageTask implements Callable<String>{
@Override
public String call() throws Exception {
Future<String> header,footer;

header = exec.submit(new Callable<String>(){
@Override
public String call() throws Exception {
System.out.println("加载页眉");
Thread.sleep(2*1000);
return "页眉";
}
});


footer = exec.submit(new Callable<String>(){
@Override
public String call() throws Exception {
System.out.println("加载页脚");
Thread.sleep(3*1000);
return "页脚";
}
});

System.out.println("渲染页面主体");

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

}

public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadDeadlock td = new ThreadDeadlock();
Future<String> futre = td.exec.submit(td.new RenderPageTask());
String result = futre.get();
System.out.println("执行结果为:" + result);

}

}


标签:exec,饥饿,RenderPageTask,死锁,线程,任务,public
From: https://blog.51cto.com/u_15905482/5919730

相关文章

  • 线程的取消和中断
    下面介绍取消线程常用的4中方式:一、通过设置“cancelled requested”标志来中断线程java中的任务取消实现:    是通过一个协作机制完成的,使用一个线程能够要求另......
  • 操作系统:银行家算法(避免死锁)
    算法介绍:程序实现:/*****************************************************程序:银行家算法实现作者:小单时间:2013年11月5日***************************......
  • 进程、线程、并行、并发、串行、进程池
    进程什么是进程?开发时编写的代码,我们称为程序。当我们运行一个程序,那么我们将运行的程序叫做进程。进程是线程的容器。程序与进程的区别程序是数据和指令的集合,是静......
  • 多线程--面试题整理
    简述线程,程序、进程的基本概念线程:与进程相似,但线程是比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空......
  • 线程协作之生产者消费者模式
    线程协作生产者消费者模式管程法packagecom.deng.gaoji;//测试生产者消费者模型--》利用缓冲区解决:管程法//生产者,消费者,产品,缓冲区publicclassTestPC{......
  • 程序、进程、线程
    一、概述程序:存放在磁盘中的可执行文件,对于计算机来说它就是一系列的指令集合,是一个静态概念进程: 程序的一次执行过程,是一个动态的概念,进程由进程控制块、程序段......
  • Tomcat最大线程数、最大连接数、超时时间及高效配置
    一、前言Tomcat作为JavaWeb程序比较常用的Servlet容器实现,在Web开发中有比较重要的地位。二、Tomcat使用的IO模式Tomcat有三种IO模式,BIO、NIO、APR。在Tom......
  • springboot2 搭建日志收集系统存入mongodb + redis+mq+线程池+xxljobs
    我们看到了高效批量插入mongodb速度还不错,那么我们的系统日志收集怎么做呢。当然当前文件日志收集效果也不错,比如前面博文写的elkf搭建日志收集系统。但我们系统中总是有......
  • java线程研究---(6)暂停Thread:join
    暂停Threadjoin方法,会让线程线程暂停,具体如下:调用方法:Thread对象.join()比如,当前有一个线程对象son,当调用了son.join()方法之后(不是child.start()方法哦),会让线程对象son的父......
  • 剖析java中几种创建线程的几种方式
    文章目录​​继承Thread​​​​实现Runnable接口​​​​实现Callable接口​​​​newThread方式的缺点​​​​通过线程池创建​​​​newSingleThreadExecutor​​​​n......