併發(1)--執行緒池簡介
通常情況下,當我們使用一個執行緒的時候,採用new方式去建立一個執行緒,這樣實現起來很方便,但是與此同時存在一個問題:大量建立執行緒,會帶來資源的消耗,並且如果併發的數量很多的時候,並且每個執行緒的執行時間很短的話,頻繁建立執行緒會很消耗效率,因為頻繁建立和銷燬執行緒是一個很耗時間的過程。
如何使得執行緒可以複用,即執行完畢並不會銷燬,進而可以執行其他的任務,那該多好啊,在java中可以通過執行緒池來達到這樣的效果。
那麼執行緒池是一個什麼樣的工作流程呢?
我們知道大量請求併發訪問的時候,伺服器不斷地建立和銷燬物件的開銷很大,所以提高伺服器效率的一個手段就是儘可能的減少建立和銷燬物件的次數,特別是一些很耗資源的物件建立和銷燬。於是基於這個,我們引入“池”的概念。何為“池”,“池”就是使得人們可以定製一定量的資源,之後對這些資源進行復用,而非頻繁的建立和銷燬。
執行緒池是預先建立執行緒的一種技術,並不是在任務到來之際建立,而是到來之前建立,並且是建立一定數量的執行緒,放入空閒佇列中,這些執行緒都是處於休眠的狀態,雖是啟動,但是並不消耗CPU,只是佔用很小的記憶體空間。
只有當請求到來的時候,執行緒池給這次請求分配一個空閒執行緒進行處理,當請求數目超過預定建立的執行緒時候,執行緒池可以自由建立一定數量的新執行緒,當系統大部分執行緒處於空閒的時候,此時執行緒池可以移除一部分處於停用狀態的執行緒。
那如果這樣的話,是不是執行緒池建立的執行緒數量越多越好呢?其實不是這樣的,執行緒池使用需要注意的是執行緒池大小與效能,併發,死鎖,資源不足以及執行緒洩露等問題。
值得注意的是:
1. 執行緒池大小,並不是越多越好,與系統執行的軟硬體有關係,一般建議與CPU數量相適合最好。
2. 併發錯誤,多執行緒容易出現併發錯誤。
3. 執行緒洩露,任務執行完畢但是執行緒並未返回執行緒池導致執行緒洩露。
下節講解執行緒池的分類使用~