线程池中的丢弃策略如果碰到队列为空或者caller线程在忙怎么办?

线程池丢弃策略为CallerRunsPolicy时,来了一个任务,发现当前运行线程已经等于最大线程数,caller线程在忙怎么办?

线程池丢弃策略为DiscardOldestPolicy时,来了一个任务,发现当前运行线程已经等于最大线程数,但这时队列为空(SynchronousQueue)时怎么办

阅读 2.8k
1 个回答

额,这个问题,问的有点奇怪。线程的拒绝策略是在队列已经满了,最大线程数也满的情况下才会接入的。
那么当调用拒绝策略的时候,队列就不应该为空。如果为空,DiscardOldestPolicy尝试丢弃最老的队列任务,把本次任务加入,那么队列为空就无法丢弃,直接把本次任务加入到第一位咯
CallerRunsPolicy如果caller在忙,就阻塞了,就等着。。


让我们看看源码

//DiscardOldestPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();//你看这里,就算队列为空,就是没有什么可以丢弃的,无法丢弃无所谓。
                e.execute(r);//然后把当前这个任务继续尝试加入
            }
        }
       
public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();//直接在当前调用线程调用了run方法,就是相对于线程池来说就是主线程调用方法,这个线程阻塞了,程序卡死,然后等到阻塞任务执行完,还是会继续走下去的
            }
        }
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题