什么是線程安全
? ??????當(dāng)多個(gè)線程訪問某個(gè)類時(shí)辅搬,不管運(yùn)行時(shí)環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行互订,并且在調(diào)用代碼中不需要任何額外的同步或者協(xié)同吧慢,這個(gè)類都能表現(xiàn)出正確的行為马靠,那么就稱這個(gè)類是線程安全的。
線程封閉的三種方式
? ? ? ? 1看蚜、ad-hoc叫搁;
? ? ? ? 2、棧封閉供炎;
? ? ? ? 3渴逻、ThreadLocal
當(dāng)不是自己的類時(shí)如何安全的發(fā)布一個(gè)類
? ??????1、委托給線程安全的類來做音诫;2惨奕、仿造Collections對(duì)容器的包裝,將內(nèi)部成員對(duì)象進(jìn)行線程安全包裝竭钝。
Serlvet不是線程安全的
? ??????1梨撞、因?yàn)槭褂脮r(shí)沒有共享的需求;2香罐、當(dāng)tomcat收到請求到最后應(yīng)答出去都是由一個(gè)線程來負(fù)責(zé)的卧波。
死鎖
? ??????兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象庇茫,若無外力作用港粱,它們都將無法推進(jìn)下去。此時(shí)稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖旦签。
? ??????多個(gè)操作者(m>=2)爭奪多個(gè)資源(N>=2)(m>=2)并且爭奪鎖的順序不對(duì)查坪。
寫一段簡單死鎖的代碼
? ??????一個(gè)方法實(shí)現(xiàn)是先獲取第一把鎖寸宏,在獲取第二把鎖,而另一個(gè)方法是先獲取第二把鎖偿曙,再獲取第一把鎖氮凝。分別用兩個(gè)線程執(zhí)行這兩個(gè)方法就會(huì)造成死鎖。
動(dòng)態(tài)死鎖
? ??????例子:銀行轉(zhuǎn)錢遥昧,張三給李四轉(zhuǎn)錢覆醇,李四給張三轉(zhuǎn)錢會(huì)出現(xiàn)死鎖。解決第一種方式:根據(jù)傳入兩個(gè)值的hash比較來獲得鎖炭臭。第二種方式:使用傳入?yún)?shù)里面的自定義鎖來嘗試獲得鎖(tryLock)來解決(容易產(chǎn)生活鎖的情況)。
活鎖
? ??????兩個(gè)線程在嘗試拿鎖的機(jī)制中袍辞,發(fā)生多個(gè)線程之間互相謙讓鞋仍,不斷發(fā)生同一個(gè)線程總是拿到同一把鎖,在嘗試拿另一把鎖時(shí)因?yàn)槟貌坏浇劣酰鴮⒈緛硪呀?jīng)持有的鎖釋放的過程威创。解決辦法:每個(gè)線程休眠隨機(jī)數(shù),錯(cuò)開拿鎖的時(shí)間谎懦。
使用線程安全的單例模式創(chuàng)建的方式
? ??????1肚豺、懶漢式的雙重檢查(基本已經(jīng)不使用了);2界拦、懶漢式的延遲初始化加載模式吸申;3、餓漢式
并發(fā)實(shí)際使用小技巧
????????為了防止多線程對(duì)同一個(gè)任務(wù)重復(fù)執(zhí)行享甸,在實(shí)現(xiàn)多線程功能時(shí)的小技巧截碴,使用新創(chuàng)建一個(gè)FutureTask,然后向conCurrentHashMap中放蛉威,如果能放不進(jìn)去說明當(dāng)前線程成功搶位了日丹,在執(zhí)行當(dāng)前線程的任務(wù)。