底層:CAS+volatile
aqs核心上是一個state(volatile),以及監控這個state的一個雙向連結清單,每個連結清單有一個節點,每個節點裝的是線程,那麼每個線程要獲得鎖,要等待,都要進入到這個等待隊列中。
(在添加隊列尾要關注前置節點,進行CAS防止線程打斷,自旋等待加到尾部,替代了sync進行鎖連結清單,這就是效率高的核心)

ReentrantLock:state記錄了線程重入了多少次,當變成0即釋放。
加入等待隊列:addWaiter方法中,用到jdk1.9 varHandle類型(指向變量的引用),可進行原子性操作(操作了普通屬性),類似反射,但效率高。
varHandle:
1.普通屬性原子性操作
2.比反射快,直接操作二進制碼
多線程通路同一個共享變量的時候容易出現并發問題,特别是多個線程對一個變量進行寫入的時候,為了保證線程安全,一般使用者在通路共享變量的時候需要進行額外的同步措施才能保證線程安全性。
ThreadLocal是除了加鎖這種同步方式之外的一種保證,一種規避多線程通路出現線程不安全的方法,當我們在建立一個變量後,如果每個線程對其進行通路的時候通路的都是線程自己的變量,這樣就不會存線上程不安全問題。
set
Thread.currentThread.map(ThreadLocal,person)
設定到了目前線程的map裡。
用途
聲明式事務,保證同一個Connection
強引用
強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。如下:
Object strongReference = new Object();
當記憶體空間不足時,Java虛拟機甯願抛出OutOfMemoryError錯誤,使程式異常終止,也不會靠随意回收具有強引用的對象來解決記憶體不足的問題。
軟引用:記憶體不夠時進行回收,多用于緩存
軟引用是用來描述一些還有用但并非必須的對象。
對于軟引用關聯着的對象,在系統将要發生記憶體溢出異常之前,将會把這些對象列進回收範圍進行第二次回收。 如果這次回收還沒有足夠的記憶體,才會抛出記憶體溢出異常。-Xmx20M
弱引用
隻要遭遇GC,直接回收,一般用于容器
為什麼Entry要使用弱引用? 若是強引用,即使tl=null,但key的引用依然指向ThreadLocal對象,是以會有記憶體洩漏,而使用弱引用則不會。 但還是會有記憶體洩露存在,ThreadLocal被回收,key的值變成null,則導緻整個value再也無法被通路到,是以依然存在記憶體洩露。 是以最終一定要remove
虛引用-堆外記憶體(給寫jvm的人所用)
一個對象是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來擷取一個對象的執行個體。 為一個對象設定虛引用關聯的唯一目的就是能在這個對象被收集器回收時收到一個系統通知。 虛引用和弱引用對關聯對象的回收都不會産生影響,如果隻有虛引用活着,弱引用關聯着對象,那麼這個對象就會被回收。它們的不同之處在于弱引用的get方法,虛引用的get方法始終傳回null, 弱引用可以使用ReferenceQueue,虛引用必須配合ReferenceQueue使用。 jdk中直接記憶體的回收就用到虛引用,由于jvm自動記憶體管理的範圍是堆記憶體,而直接記憶體是在堆記憶體之外(其實是記憶體映射檔案),是以直接記憶體的配置設定和回收都是有Unsafe類去操作,java在申請一塊直接記憶體之後,會在堆記憶體配置設定一個對象儲存這個堆外記憶體的引用, 這個對象被垃圾收集器管理,一旦這個對象被回收,相應的使用者線程會收到通知并對直接記憶體進行清理工作。事實上,虛引用有一個很重要的用途就是用來做堆外記憶體的釋放,DirectByteBuffer就是通過虛引用來實作堆外記憶體的釋放的。