線程池原理?爲什麼要用線程池?線程池的創建方式?

爲什麼要使用線程池

在面向對象編程中,對象創建和銷燬是很費時間的,因爲創建一個對象要獲取內存資源或者其它更多資源。在Java中更是如此,虛擬機將試圖跟蹤每一個對象,以便能夠在對象銷燬後進行垃圾回收。所以提高服務程序效率的一個手段就是儘可能減少創建和銷燬對象的次數,特別是對一些很耗資源的對象創建和銷燬。如何利用已有對象來服務就是一個需要解決的關鍵問題,其實這就是一些"池化資源"技術產生的原因。比如大家所熟悉的數據庫連接池就是遵循這一思想而產生的,下面將介紹的線程池技術同樣符合這一思想。

多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閒置時間,增加處理器單元的吞吐能力。但如果對多線程應用不當,會增加對單個任務的處理時間。可以舉一個簡單的例子:

假設一臺服務器完成一項任務的時間爲T

 T1 創建線程的時間
 T2 在線程中執行任務的時間,包括線程間同步所需時間> 
 T3 線程銷燬的時間

顯然T = T1+T2+T3。注意這是一個極度簡化的假設。

可以看出T1,T3是多線程本身附加的開銷,用戶希望減少T1,T3所用的時間,從而減少T的時間。但一些線程的使用者並沒有注意到這一點,所以在應用程序中頻繁的創建或銷燬線程,這導致T1和T3在T中佔有非常大的比例。

線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高服務器程序性能的。它把T1,T3分別安排在服務器程序的啓動和結束的時間段或者一些空閒的時間段,這樣在服務器程序處理客戶請求時,不會有T1,T3的開銷了,線程池不僅調整T1,T3產生的時間,而且它還顯著減少了創建線程的數目。

創建線程&線程池

參考url

java創建線程的三種方式:

繼承Thread類創建線程類
實現Runnable接口
通過Callable和Future創建線程

java創建線程池的四種方式:

 newCachedThreadPool 創建一個可緩存的線程池,如果線程池長度超過處理需求,可靈活回收空閒線程,若無可回收,則新建線程

newFixedThreadPool 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待

newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行

newSingleThreadExecutor 創建一個單線程化的線程池,它只會唯一的工作線程來執行任務,保證所有任務按照指定
順序(FIFO,LIFO,優先級)執行

線程池的好處~

通過重複利用已創建的線程,減少在創建和銷燬線程上所花的時間以及系統資源的開銷。

提高響應速度,當任務到達時,任務可以不需要等到線程創建就可以立即執行。 提高線程的可管理性,使用線程池可以對線
程進行統一的分配和監控。

如果不使用線程池,有可能造成系統創建大量線程而導致消耗完系統內存。

線程池的注意事項:

線程池的大小:多線程應用並非線程越多越好。需要根據系統運行的硬件環境以及應用本身的特點決定線程池的大小。一般來說,如果代碼結構合理,線程數與cpu數量相適合即可。如果線程運行時可能出現阻塞現象,可相應增加池的大小、如果有必要可採用自適應算法來動態調整線程池的大小。以提高cpu的有效利用率和系統的整體性能。
併發錯誤:多線程應用要特別注意併發錯誤,要從邏輯上保證程序的正確性,注意避免死鎖現象的發生。
線程泄露:這是線程池應用中的一個嚴重的問題、當任務執行完畢而線程沒能返回池中就會發生線程泄露現象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章