2017-10-10 74 views
0

我有下面的代碼:理解的ThreadPoolExecutor內部工作

public class ExecFramework implements Runnable { 
int i; 

public ExecFramework() { 

} 

public ExecFramework(int i) { 
    this.i = i; 
} 

public void run() { 
    System.out.println(Thread.currentThread().getName() + " " + i); 
    try { 
     Thread.sleep(10); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

public static void main(String[] args) { 

    ExecutorService pool=new ThreadPoolExecutor(2, 10, 5000,TimeUnit.SECONDS, new ArrayBlockingQueue(2)); 
    for (int i = 0; i < 20; i++) { 
     Runnable obj=new ExecFramework(i); 
     pool.execute(obj); 
    } 
    pool.shutdown(); 
    while(pool.isTerminated()){ 
     System.out.println("ExecutorService is terminated"); 
    } 

} 

}

是我的ThreadPoolExecutor工作正確的方式認識:

  1. 如果NumberOfThreadRunning < CoreNumberOfThreads隨後的ThreadPoolExecutor創建一個新的線程來完成任務。
  2. 如果NumberOfThreadRunning> CoreNumberOfThreads會將此任務排列在BlockingQueue中,但如果隊列已滿,則僅在 NumberOfThread < MaxNumberOfThreads時創建新線程。
  3. 一旦任務完成,線程運行該任務可用於其他任務。

根據第3點。我應該能夠使用ThreadPoolExecutor執行20個任務。

爲什麼輸出上面的代碼是?

pool-1-thread-5 6 
 
pool-1-thread-4 5 
 
pool-1-thread-3 4 
 
pool-1-thread-1 0 
 
pool-1-thread-2 1 
 
pool-1-thread-6 7 
 
pool-1-thread-7 8 
 
pool-1-thread-8 9 
 
pool-1-thread-9 10 
 
pool-1-thread-10 11 
 
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Running, pool size = 10, active threads = 10, queued tasks = 2, completed tasks = 0] 
 
\t at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) 
 
\t at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) 
 
\t at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) 
 
\t at executionFramework.ExecFramework.main(ExecFramework.java:88) 
 
pool-1-thread-8 2 
 
pool-1-thread-6 3

回答

0

文檔指出:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html

在第拒絕任務的

在你的情況,我會想這:

當執行器同時用於最大線程和工作隊列容量有限的範圍,並且飽和

發生。

+0

我對ThreadPoolExecutor的理解是否正確?在我的問題中給出了3分 – user2708837

+0

每當我們調用ThreadPoolExecutor上的execute時,它總是在ThreadPoolExecutor中創建一個新的Thread? – user2708837

+0

否ThreadPoll會根據需要創建線程直至定義的最大值。當你像工作一樣給出一個工作隊列,並且這個隊列已經飽和時,就沒有可用的線程了。儘量不要提供這個工作隊列或者只是讓它變大。工作隊列保存可運行的內容,直到它們被髮布給執行者。在你的情況下,執行程序中的線程繁忙,並且保持可運行程序被轉發到池的隊列也已滿 –