java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1768) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:767) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:658)
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
通過如下方式創建線程池:
AbstractExecutorService executor=new ThreadPoolExecutor(3,10,30L,TimeUnit.SECONDS,new SynchronousQueue(),new ExecutorThreadFactory("ThrowableThreadPoolExecutor"),new AbortPolicy());
new ExecutorThreadFactory("ThrowableThreadPoolExecutor")簡單的封裝了ThreadFactory
由於SynchronousQueue並不是一個真正的隊列,而是一種管理直接在線程間移交信息的機制,為了把一個元素放入到SynchronousQueue中,必須有另一個線程正在等待接受移交的任務。如果沒有這樣一個線程,只要當前池的大小還小於最大值,ThreadPoolExcutor就會創建一個新的線程;否則根據飽和策略,任務會被拒絕。而設置的飽和策略恰恰是new AbortPolicy(),當線程池滿了后,execute拋出未檢查的RejectedExecutionException,線程丟失。可以通過捕獲該異常做相應的補救處理。
另外的處理方式是設置線程池的隊列的飽和策略,線程池創建如下:
AbstractExecutorService executor = new ThrowableThreadPoolExecutor(10,40, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
new ExecutorThreadFactory("ThrowableThreadPoolExecutor"), new ThreadPoolExecutor.CallerRunsPolicy());
當任務向線程池請求要分配線程時,線程池處理如下:
1、如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閑狀態,也要創建新的線程來處理被添加的任務
2、如果此時線程池中的數量等於 corePoolSize,但是緩沖隊列 workQueue未滿,那么任務被放入緩沖隊列