線程基礎(chǔ)、線程之間的共享和協(xié)作

java的引用

????(1) 、強(qiáng)引用:程序中普遍存在的。類似:“Object o = new Object();”,只要引用還存在,垃圾回收器就不會(huì)回收被引用的對(duì)象實(shí)例。

????(2)?、軟引用:用來描述一些有用但是非必須的對(duì)象,對(duì)于軟引用關(guān)聯(lián)的對(duì)象,在系統(tǒng)將要發(fā)生內(nèi)存溢出之前,將會(huì)把這些對(duì)象實(shí)例列進(jìn)回收范圍內(nèi)進(jìn)行二次回收(相當(dāng)于多了一次被回收的機(jī)會(huì)),如果這次垃圾回收還沒有足夠的內(nèi)存,才會(huì)跑出內(nèi)存溢出的異常。使用SoftReference類實(shí)現(xiàn)軟引用。

????(3)?、弱引用:用來描述非必需的對(duì)象。但它的強(qiáng)度比軟引用更弱一些,被軟引用的對(duì)象實(shí)例只能存活到下次垃圾回收之前。當(dāng)下次垃圾回收時(shí),無論內(nèi)存是否足夠,都會(huì)回收掉被軟引用的對(duì)象實(shí)例。使用WeakReference類實(shí)現(xiàn)弱引用。ThreadLocal中的就是軟引用。

????(4)?、虛引用:也被稱為幽靈引用或者幻影引用。是最弱的一種引用。為一個(gè)對(duì)象設(shè)置虛引用的唯一目的就是在這個(gè)對(duì)象實(shí)例在被垃圾回收器回收時(shí)收到一個(gè)系統(tǒng)通知。使用PhantomReference類來實(shí)現(xiàn)。

ThreadLocal

? ? ?原理:每一個(gè)Thread都維護(hù)一個(gè)ThreadLocalMap,這個(gè)映射表的key就是ThreadLocal實(shí)例本身,value是真正存儲(chǔ)的值,實(shí)際上ThreadLocal并不存儲(chǔ)值,而只是作為一個(gè)key從ThreadLocalMap中獲取value值。這個(gè)map是使用ThreadLocal的弱引用作為key的,弱引用在gc時(shí)會(huì)被回收。

????ThreadLocal使用時(shí)會(huì)造成兩個(gè)問題:

????(1) 內(nèi)存泄漏:由于ThreadLocalMap的生命周期跟Thread 一樣長,如果沒有手動(dòng)刪除對(duì)應(yīng)key 就會(huì)導(dǎo)致內(nèi)存泄漏,而不是因?yàn)槿跻谩Mㄟ^調(diào)用set,get以及remove方法來回收弱引用。使用完畢后調(diào)用remove可以避免。

????(2) 線程不安全:ThreadLocal本質(zhì)上保存的是一個(gè)引用,而ThreadLocal指向的是同一個(gè)對(duì)象的時(shí)候,當(dāng)有一個(gè)對(duì)象改了里面的數(shù)據(jù),其他線程訪問的時(shí)候,訪問的是堆上這個(gè)對(duì)象唯一的實(shí)例。如何避免:對(duì)于每一個(gè)線程而言,應(yīng)該new出來一個(gè)單獨(dú)的對(duì)象給ThreadLocal。

等待和通知的標(biāo)準(zhǔn)范式

????等待

????????Syn(對(duì)象){

????????????While(條件不滿足){

????????????????對(duì)象.wait();

????????????}

????????????//處理業(yè)務(wù)邏輯

????????}

????通知

????????Syn(對(duì)象){

????????????//業(yè)務(wù)邏輯,改變條件

????????????對(duì)象.notify()/notifyAll();

????????}

鎖的幾點(diǎn)說明

????1、一個(gè)對(duì)象調(diào)用了wait方法后,會(huì)釋放掉這個(gè)對(duì)象的鎖,而notify()和notifyAll()不會(huì)釋放鎖,只有在執(zhí)行完syn代碼塊后才會(huì)釋放鎖。

? ? 2、錯(cuò)誤加鎖的原因其實(shí)是對(duì)象有變化了,導(dǎo)致加鎖失敗

? ? 3、Volatile關(guān)鍵字其實(shí)是最輕量級(jí)的鎖,原因是volatile獲取的最新的值,用在一寫多讀的場景中

? ? 4、調(diào)用yield()、sleep()、wait()、notify()等方法對(duì)鎖有何影響?

? ? ? ? 答:yield()、sleep()被調(diào)用后,都不會(huì)釋放當(dāng)前線程所持有的鎖。調(diào)用wait()方法后,會(huì)釋放當(dāng)前線程持有的鎖,而且當(dāng)前被喚醒后,會(huì)重新去競爭鎖,鎖競爭到后才會(huì)執(zhí)行wait 方法后面的代碼。調(diào)用notify()系列方法后,對(duì)鎖無影響,線程只有在syn 同步代碼執(zhí)行完后才會(huì)自然而然的釋放鎖,所以notify()系列方法一般都是syn 同步代碼的最后一行。

????5、數(shù)據(jù)庫的連接池都是使用了等待超時(shí)模式實(shí)現(xiàn)的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容