线程饥饿死锁

来源:互联网 发布:重庆seo服务 编辑:程序博客网 时间:2024/06/10 01:32

线程饥饿死锁:

      在一个线程池中,如果一个任务依赖于其他任务的执行,就可能产生死锁。对应一个单线程话的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>{@Overridepublic String call() throws Exception {Future<String>  header,footer;header = exec.submit(new Callable<String>(){@Overridepublic String call() throws Exception {System.out.println("加载页眉");Thread.sleep(2*1000);return "页眉";}});footer = exec.submit(new Callable<String>(){@Overridepublic 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);}}

0 0