多线程与高并发(五):强软弱虚四种引用以及ThreadLocal的原理与源码
上節回顧
AQS(CLH的變種)
因為新加進來的節點要查看前面的節點的狀態,所以使用的是雙向鏈表。
AQS的底層是 CAS + Volitile,用CAS替代了鎖整個鏈表的操作。
公平鎖:上來先排隊
非公平鎖:上來直接搶鎖
state 根據子類不同的實現,取不同的意義。
AQS類中有一個內部類Node,里面裝的是它的成員變量Thread。很多Node組成一個雙向鏈表,就是一個等待隊列。
非公平的時候,如果搶不到鎖,就進入隊列繼續等待。
如果搶到了,就用CAS的方式設定當前線程為獨占這把鎖的線程。
VarHandle
面試用,實際項目幾乎沒用,講出來讓別人聽不懂…
- 普通屬性也可以進行原子操作
- 比反射快,直接操作二進制碼
- jdk1.9之后才有(下面這個程序,我用11.0.3會報錯找不到包,暫時沒有找到原因)
ThreadLocal
ThreadLocal 修飾的變量,是線程獨有的
為什么要有ThreadLocal?
Spring的聲明式事務會用到。
Spring的聲明式事務在一個線程里。
connection在連接池里,不同的connection之間怎么形成完整的事務?
把connection放在當先線程的ThreadLocal里面,以后拿的時候從ThreadLocal直接拿,不去線池里面拿。
ThreadLocal是怎么做到的?
222行的this是當前的ThreadLocal對象。
ThreadLocalMap是當前Thread的一個成員變量。
強軟弱虛四種引用
之前寫過完整的博客:
【Java】強軟虛弱引用類型;弱引用在ThreadLocal中的應用
在垃圾回收的時候,各種引用類型的表現?
強引用
Object strongReference = new Object();只要有引用指向它,就不會被回收。
當內存空間不足時,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。
如果強引用對象不使用時,需要 strongReference = null;從而使GC能夠回收
軟引用
內存空間不夠時,軟引用會被回收。
主要用來做緩存。
弱引用
弱引用與軟引用的區別在于:只具有弱引用的對象,擁有更短暫的生命周期。
在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。
不過,由于垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。
弱引用一般用在容器里,如:WeakHashMap。如果有一個強引用指向弱引用,當強引用消失之后,這個弱引用就也應該會消失。
典型應用:ThreadLocal
虛引用
虛引用顧名思義,就是形同虛設,使用get也無法獲取到虛引用的值。與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用與軟引用和弱引用的一個區別在于:
虛引用必須和引用隊列(ReferenceQueue)聯合使用。
當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。
總結
以上是生活随笔為你收集整理的多线程与高并发(五):强软弱虚四种引用以及ThreadLocal的原理与源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM从入门到精通(四):内存屏障与JV
- 下一篇: Redis实战(四):redis的消息订