线程饥饿锁

2020-09-25  本文已影响0人  黄殿玺

java并发编程实战(Brian Goetz)中描述:


image.png

结论1:在线程池中,如果任务依赖于其他任务,那么可能产生死锁。
结论2:在单线程池中,如果一个任务将另一个任务提交到同一个Executor,并且等待这个被提交的任务结果,那么通常会引发死锁。

先验证结论2

package java_concurrent;

import java.util.concurrent.*;

public class ThreadDeadlock {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //同一个线程池
        ExecutorService es = Executors.newFixedThreadPool(1);

        Future f = es.submit(new RenderPageTask(es));
        System.out.println("s1");
        System.out.println(f.get());
        System.out.println("s4");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        es.shutdown();
    }

}

//任务1
class RenderPageTask implements Callable<String>{

    ExecutorService es;

    public RenderPageTask(ExecutorService es){
        this.es = es;
    }

    @Override
    public String call() throws Exception {
        System.out.println("task1 call....");
        Future<String> header, footer;
        header = es.submit(new LoadFileTask(es, "header.html"));
        System.out.println("s2");
        //将发生死锁因为,由于任务等待子任务的结果
        String h = header.get();
        System.out.println("s3");
        return h;
    }
}

//任务2
class LoadFileTask implements Callable<String>{
    ExecutorService es;
    String s;

    public LoadFileTask(ExecutorService es, String s){
        this.es = es;
        this.s = s;
        System.out.println(s);
    }

    @Override
    public String call() throws Exception {
        System.out.println("task2 call....");
        return this.s;
    }
}

输出结果是

上一篇 下一篇

猜你喜欢

热点阅读