两个线程池死锁

 public static void scheduleCreateRequest() {
        createRequestExecutor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"start");

                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"end");
            }
        });
        System.out.println("submit finished");

    }
    public static void main (String[] args) throws InterruptedException {
        createRequestExecutor=new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>(),new ThreadPoolExecutor.DiscardOldestPolicy());

        createRequestScheduled= Executors.newScheduledThreadPool(1);
        createRequestScheduled.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println(new Date());
                scheduleCreateRequest();
            }
        }, 0, 1, TimeUnit.SECONDS);
        System.out.println("finished");

    }

以上代码会造成“死锁”

条件1

createRequestExecutor 中只有一个线程,并且使用了同步队列SynchronousQueue,拒绝策略DiscardOldestPolicy
此时当有线程在执行时,createRequestScheduled第二次提交时,拒绝策略直接生效

if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
}

会继续执行,依然拒绝,继续重复execute,直到StackOverflow。

条件2

createRequestScheduled捕获到StackOverflowError后,不再增加下一次的task。

if (ScheduledFutureTask.super.runAndReset()) {//Error返回false
                setNextRunTime();
                reExecutePeriodic(outerTask);
 }

但createRequestScheduled的线程池会继续从队列中take数据,此时由于队列为空,会await。但是已经没有线程再add。就会一直wait下去。
而createRequestExecutor在执行完第一次后,也因为没有schedule调度而一直wait。都停止运行。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java-Review-Note——4.多线程 标签: JavaStudy PS:本来是分开三篇的,后来想想还是整...
    coder_pig阅读 5,596评论 2 17
  • 【JAVA 线程】 线程 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者...
    Rtia阅读 7,720评论 2 20
  • 作者:肥肥鱼链接:https://www.zhihu.com/question/30804052/answer/4...
    TTTqiu阅读 4,535评论 0 4
  • 第6章介绍了任务执行框架, 它不仅能简化任务与线程的生命周期管理, 而且还提供一 种简单灵活的方式将任务的提交与任...
    好好学习Sun阅读 4,908评论 0 2
  • 线程的两种创建方式:继承Thread类或者实现Runnable接口,Thread类本质上是实现了Runnable接...
    繁星追逐阅读 3,800评论 0 1