五、兩個重要概念Sizes與Queues
Size
一個線程庫創建後,其的大小在最小值(corePoolSize)與最大值(maximumPoolSize)之間,運行時可根據getPoolSize()確定其當前的大小。
Queue
隊列用於存放等候執行的任務。
下面一步步分析這兩個值在線程庫的工作中是如何運作:
1. ThreadPoolExecutor tpe = new ThreadPoolExecutor(M, N, TIMEOUT, TimeUnit.MILLISECONDS,
2. new LinkedBlockingQueue<Runnable>());
3.
4. Task[] tasks = new Task[nTasks];
5. for (int i = 0; i < nTasks; i++) {
6. tasks[i] = new Task(n, "Task " + i);
7. tpe.execute(tasks[i]);
8. }
9. tpe.shutdown();
行1-2構造了一個線程庫,M個core threads和N maximum threads,這時實際上並沒有線程被創建。(可能過prestartAllCoreThreads() 和 prestartCoreThread() 方法分別預先創建)
第7行 一個任務被加入到線程庫,這時下列5種情況之一將會發生:
如果庫中的線程數少於M,線程庫將立即啟動一個新的線程來運行這個任務。即使庫中有空閒的線程,仍然會產生一個新線程直到數量到達M。
如果庫中的線程數在M和N之間,並且只少有一個是空閒線程,那麼任務將由這個空閒線程執行。
如果庫中的線程數在M和N之間,並且沒有空閒線程,這時庫會檢查存在的工作隊列,如果任務能夠放置在隊列中而不被阻塞,那麼任務就會放置在該列隊中,不會有新的線程啟動。
如果庫中的線程數在M和N之間,並且沒有空閒線程,且任務不能無阻塞地加入到隊列中,這時庫會開始一個新線程來運行這個任務。
如果庫中的線程數量已到達N且沒有空閒線程,這時庫將會試著放置新任務到一個隊列。如果該隊列已到達它的最大大小,任務將會被拒絕,添加失敗,否則任務將被接受等待有空閒的線程來運行它。
一個任務執行完成,運行這個任務的線程將去運行隊列中的下一個任務,如果隊列中沒有任務,將會發生下面兩種情況之一:
如果庫中的線程數大於M,線程將等待一個隊列中有新的任務。如果隊列中的新任務沒有超時,該線程將運行這個任務,否則線程將退出以減少庫中的線程數量。超時值是在新構造線程庫時指定的TIMEOUT,如果TIMEOUT為0,不管庫的最小大小(corePoolSize)是多少,線程執行完任務後總是退出。
如果庫中的線程數量等於M或小於M,該線程將不確定地被阻塞以等待一個新的任務被加入到隊列(除非TIMEOUT=0,它將退出),當它有效時就會運行這個新任務。
本文來自編程入門網:http://www.bianceng.cn/Programming/Java/201105/26712_2.htm