美文网首页
两个线程池死锁

两个线程池死锁

作者: 机智的河道蟹 | 来源:发表于2019-08-22 12:07 被阅读0次
     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。都停止运行。

    相关文章

      网友评论

          本文标题:两个线程池死锁

          本文链接:https://www.haomeiwen.com/subject/cocnsctx.html