1. 程式人生 > >線程池與Threadlocal

線程池與Threadlocal

線程池 一個 read bsp 其他 覆蓋 調用 img hash

線程池與Threadlocal

線程池: 線程池是為了使線程能夠得到循環的利用,線程池裏面養著一些線程,有任務需要使用線程的時候就往線程池裏抓線程對象出來使用。線程池裏的線程能夠重復使用,所以在資源上能夠得到比較好的利用。 在任務數量多的時候就適合使用線程池,因為總不可能將線程無限的開啟下去,萬一任務數量有幾千的話就得開幾千個線程,這樣對於資源上就比較浪費了。如果使用線程池的話,就能重復的利用線池裏的線程,就不需要一直新開啟線程,所有的線程就能得到很好的循環利用。

線程池的開啟方式:

線程池通過Executors類來開啟,線程池有幾種類型,有固定線程數量的,有不固定數量的,有具備定時功能的,還有單線程的。

1.創建固定線程數量的線程池:

技術分享

運行結果:

技術分享

2.創建不固定線程數量的線程池:

技術分享

運行結果:

技術分享

3.創建具備定時功能的線程池:

技術分享

運行結果:

技術分享

4.創建單線程池:

技術分享

運行結果:

技術分享

Threadlocal類:

說Threadlocal類之前,先看看一個問題。如果有A、B、C、D、E這幾個方法,這幾個方法除了A方法外都不具備參數,但是想要從A方法將一個值傳遞到E方法上去怎麽辦?仔細想一想似乎使用一個靜態屬性作為一個中間介質就可以實現到傳遞的效果。

示意圖:

技術分享

雖然咋看之下好像沒什麽問題,但是問題在於如果是多個線程同時去調用的話,就會出現值被覆蓋的問題了,數據上就會出現混亂了。

代碼示例: 技術分享 技術分享

運行結果:

技術分享

從代碼的運行結果可以看出,數據有被覆蓋的現象。這時候可能會有人說,每次都構建Test1的對象來進行調用就可以避免出現這種問題了。是的,的確每次構建一個對象就能避免這種問題的出現,但是萬一是靜態的情況呢,不是說在開發的過程中都只會出現一種情況,所以如果是這種靜態的情況,使用這個辦法就沒辦法解決了,甚至還會出現問題。

雖然上面這種辦法用在實例的情況下還行,不過還有另一種方法,就是使用Hashtable集合就能解決這個問題,Hashtable集合是鍵值對集合,一個鍵對應著一個值。因為這種特性,我們可以將線程的名稱作為鍵值,然後對應存儲這個線程所帶的值,接著存放在Hashtable集合裏。這樣,在方法中取值的時候就能取到與線程相對應的值了,所以其他線程的值就不會被覆蓋了,使用這個方法就能解決靜態的情況了。

正題到了,使用Hashtable集合還是稍微有點麻煩,所以還有一種更方便的解決方式就是使用Threadlocal類,使用Threadlocal類的set將值設置進去,再使用get方法得到值就可以了,都不需要設置鍵值,比起Hashtable要方便一些。

代碼示例:

技術分享 技術分享

運行結果:

技術分享

線程池與Threadlocal