ThreadPoolExecutor 的 execute() 到底怎么决定进队列还是创建线程?不同队列会怎样?任务抛异常线程会怎样?这篇用真实的线程池把每一步量出来(拒绝策略的四种表现已有专门的文章)。
core=2, max=4, 队列容量=2。依次提交 7 个会阻塞的任务: 任务 1:已接受 → 线程数 0 → 1,队列里 0 任务 2:已接受 → 线程数 1 → 2,队列里 0 任务 3:已接受 → 线程数 2 → 2,队列里 1 任务 4:已接受 → 线程数 2 → 2,队列里 2 任务 5:已接受 → 线程数 2 → 3,队列里 2 任务 6:已接受 → 线程数 3 → 4,队列里 2 任务 7:被拒绝(RejectedExecutionException) → 线程数 4 → 4,队列里 2
LinkedBlockingQueue(无界) core=2 max=8,提交 30 个阻塞任务:线程数 2,队列 28,被拒绝 0 ArrayBlockingQueue(20) core=2 max=8,提交 30 个阻塞任务:线程数 8,队列 20,被拒绝 2 SynchronousQueue core=2 max=8,提交 30 个阻塞任务:线程数 8,队列 0,被拒绝 22
同时有 6 个任务在跑:线程数 6(最大 6) 任务结束后 ~0 ms:线程数 6 任务结束后 ~200 ms:线程数 6 任务结束后 ~500 ms:线程数 2 任务结束后 ~1000 ms:线程数 2 allowCoreThreadTimeOut(true) 之后再等 500 ms:线程数 0
execute 的任务在 worker-1 里运行并抛异常 execute 的任务在 worker-2 里运行并抛异常 execute 的任务在 worker-3 里运行并抛异常 [未捕获异常处理器] worker-3 收到 java.lang.IllegalStateException: boom [未捕获异常处理器] worker-1 收到 java.lang.IllegalStateException: boom [未捕获异常处理器] worker-2 收到 java.lang.IllegalStateException: boom execute 抛了 3 次异常之后,线程工厂一共创建过 [worker-1, worker-2, worker-3, worker-4](每次异常都换了新线程) submit 抛了 3 次异常之后,线程工厂创建过 [worker-s1];未捕获异常处理器没有被调用 只有调用 future.get() 才看到:java.lang.IllegalStateException: boom