線程池與Threadlocal
線程池: 線程池是為了使線程能夠得到循環(huán)的利用蚜锨,線程池里面養(yǎng)著一些線程县踢,有任務需要使用線程的時候就往線程池里抓線程對象出來使用。線程池里的線程能夠重復使用,所以在資源上能夠得到比較好的利用症昏。 在任務數量多的時候就適合使用線程池,因為總不可能將線程無限的開啟下去父丰,萬一任務數量有幾千的話就得開幾千個線程肝谭,這樣對于資源上就比較浪費了。如果使用線程池的話,就能重復的利用線池里的線程攘烛,就不需要一直新開啟線程魏滚,所有的線程就能得到很好的循環(huán)利用。
線程池通過Executors類來開啟坟漱,線程池有幾種類型鼠次,有固定線程數量的,有不固定數量的靖秩,有具備定時功能的须眷,還有單線程的。
1.創(chuàng)建固定線程數量的線程池:
運行結果:
2.創(chuàng)建不固定線程數量的線程池:
運行結果:
3.創(chuàng)建具備定時功能的線程池:
運行結果:
4.創(chuàng)建單線程池:
運行結果:
說Threadlocal類之前沟突,先看看一個問題花颗。如果有A、B惠拭、C扩劝、D、E這幾個方法职辅,這幾個方法除了A方法外都不具備參數棒呛,但是想要從A方法將一個值傳遞到E方法上去怎么辦?仔細想一想似乎使用一個靜態(tài)屬性作為一個中間介質就可以實現到傳遞的效果域携。
示意圖:
雖然咋看之下好像沒什么問題簇秒,但是問題在于如果是多個線程同時去調用的話,就會出現值被覆蓋的問題了秀鞭,數據上就會出現混亂了趋观。
代碼示例:
運行結果:
從代碼的運行結果可以看出,數據有被覆蓋的現象锋边。這時候可能會有人說皱坛,每次都構建Test1的對象來進行調用就可以避免出現這種問題了。是的豆巨,的確每次構建一個對象就能避免這種問題的出現剩辟,但是萬一是靜態(tài)的情況呢,不是說在開發(fā)的過程中都只會出現一種情況往扔,所以如果是這種靜態(tài)的情況贩猎,使用這個辦法就沒辦法解決了,甚至還會出現問題瓤球。
雖然上面這種辦法用在實例的情況下還行融欧,不過還有另一種方法,就是使用Hashtable集合就能解決這個問題卦羡,Hashtable集合是鍵值對集合噪馏,一個鍵對應著一個值麦到。因為這種特性,我們可以將線程的名稱作為鍵值欠肾,然后對應存儲這個線程所帶的值瓶颠,接著存放在Hashtable集合里。這樣刺桃,在方法中取值的時候就能取到與線程相對應的值了粹淋,所以其他線程的值就不會被覆蓋了,使用這個方法就能解決靜態(tài)的情況了瑟慈。
正題到了桃移,使用Hashtable集合還是稍微有點麻煩,所以還有一種更方便的解決方式就是使用Threadlocal類葛碧,使用Threadlocal類的set將值設置進去借杰,再使用get方法得到值就可以了,都不需要設置鍵值进泼,比起Hashtable要方便一些蔗衡。
代碼示例:
運行結果: