2017-11-04 286 views
0

下面是我的方法,我有單線程執行程序來執行run方法中的某個任務。RejectedExecutionException來自單線程執行程序

private void trigger(final Packet packet) { 

    // this line is throwing exception 
    Executors.newSingleThreadExecutor().execute(new Runnable() { 
     @Override 
     public void run() { 
     // some code here 
     } 
    }); 
    } 

下面是我得到的例外,我不知道爲什麼?解決這個問題的最好方法是什麼?

error= java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0] 
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048) 
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821) 
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372) 
    at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:628) 

如果我的trigger方法被調用許多次,它仍然是在我以前的線程的run方法的工作,會發生什麼?它會啓動多個線程,還是等待一個線程完成,然後啓動另一個線程?

+0

是的,這是完整的代碼,我也提到了它拋出異常的地方。 – user1950349

+0

您使用的是哪個版本的JDK? –

+0

我正在使用JDK7。 – user1950349

回答

1

在這裏看到:What could be the cause of RejectedExecutionException

,你可以從錯誤日誌中看到,您的ThreadPoolExecutor被終止。

也許這是你想要什麼:

private void trigger(final Packet packet) { 

    executor.execute(new Runnable() { 
     @Override 
     public void run() { 
     // some code here 
     } 
    }); 
    } 

private final ExecutorService executor = Executors.newFixedThreadPool(10); 

編輯重現問題有:

public static void main(String[] args) { 
    final ExecutorTest et = new ExecutorTest(); 
    for (int i = 0; i < 50000; i++) { 
     et.trigger(i); 
    } 
    System.out.println("Done"); 
} 

private void trigger(int i) { 

    try { 
     Executors.newSingleThreadExecutor().execute(() -> { 
      try { 
       Thread.sleep(1000); 
      } catch (final InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     }); 
    } catch (final Exception e) { 
     System.out.println("Test " + i + " with " + Thread.activeCount()); 
     e.printStackTrace(); 
    } 
} 
+0

終止是指什麼?爲什麼它終止? – user1950349

+0

嘗試從服務將要終止時從文檔和代碼中找出。但目前我沒有答案。還嘗試了長時間運行線程和多次調用的小樣本事件。沒有問題。你有沒有感覺我的方法觸發了多少次?這些調用是單線程還是多線程? – IEE1394

+0

我可以用50000次調用重現你的問題,執行時會延遲一秒 - 所以我想你的資源有問題 – IEE1394

0

創建ThreadPoolExecutor之外的觸發方法。每次打電話都不應創建newSingleThreadExecutor

private ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 
private void trigger(final Packet packet) { 

executorService .execute(new Runnable() { 
    @Override 
    public void run() { 
    // some code here 
    } 
}); 

}

關於你的例外,請execute方法的說明。

public void execute(Runnable command) 

Executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread. If the task cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been reached, the task is handled by the current RejectedExecutionHandler.

因爲它是無界隊列,極可能是你叫shutdown一些別的地方在你的代碼。

+0

因此,你認爲我應該創建一個固定的線程池,然後使用它來代替每次使用單線程執行程序? – user1950349

+0

是的。並且不要在關機後向它提交任務。 –