java.util.concurrent.RejectedExecutionException

gary-liu發表於2018-04-01

問題

最近在用執行緒池寫程式碼跑任務時拋了這個java.util.concurrent.RejectedExecutionException異常,於是就查 了下自己的程式碼,原因是執行緒池呼叫shutdown()後,又執行了新任務。在shutdown()執行前,老的任務會繼續處理而不允許在提交新的任務。

注:分析和解決可以直接看參考資料中的兩篇文章十分詳細

原因

產生該異常一般有兩個原因:
1.執行緒池呼叫shutdown()後,又執行了新任務。
2.當執行緒池的排隊策略為有界佇列,而提交的任務超過了有界佇列的長度時,就會拋該異常。所以排隊策略可以不用有界佇列,但注意任務太多無界佇列可能記憶體溢位。

示例

這裡只列出我遇到的第一個原因產生的異常。

public static void test(){
        ExecutorService executorService = new ThreadPoolExecutor(5, 10,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());

        for(int j = 0; j < 5; j++){
            List<Integer> list = Lists.newArrayList();
            for(int i = 0; i < 5000; i++){
                list.add(i);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(Integer integer : list){
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {

                            System.out.println(integer);
                            Thread.sleep(1000);
                        } catch (Exception e) {

                            System.out.println(e);
                        }
                    }
                });
            }
            //不能寫在這裡會拋異常
            //executorService.shutdown();
        }
        //應該寫在最後這裡
        executorService.shutdown();
    }

參考資料

java.util.concurrent.RejectedExecutionException – How to solve RejectedExecutionException
java.util.concurrent.RejectedExecutionException