产生该异常一般有两个原因:
1.线程池调用shutdown()后,又执行了新任务。
2.当线程池的排队策略为有界队列,而提交的任务超过了有界队列的长度时,就会抛该异常。所以排队策略可以不用有界队列,但注意任务太多无界队列可能内存溢出。(拒绝策略)
如下线程池的承载的最多任务数量:maximumPoolSize(5)+workQueue(3)=8,但是却又9个任务交给了线程池。
public static void main(String[] args) {
// ExecutorService threadPool = Executors.newSingleThreadExecutor(); // 只有一个线程的线程池
// ExecutorService threadPool = Executors.newFixedThreadPool(5); // 创建一个有固定线程数的线程池
// ExecutorService threadPool = Executors.newCachedThreadPool(); // 线程数目可调节的线程池,遇强则强,遇弱则弱
// 获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());
// 自定义线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy());// 拒绝策略:队列满了,尝试去和最早的任务竞争(因为最早执行的任务可能最早结束),如果竞争成功就执行,失败就把任务丢掉。
try {
for (int i = 1; i <= 9; i++) {
int finalI = i;
threadPool.execute(() -> {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " --- ok --- " + finalI);
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程用完,程序结束,关闭线程池
threadPool.shutdown();
}
}