一隻魚 -
synchronized
synchronized為什麼是可重入的
簡單理解就是當前線程已經持有了對象鎖,當前線程可以繼續訪問
synchronized底層使用的是lock+cmpxchg
synchronized是非公平鎖,當一個線程要獲取鎖時,先試圖插隊,如果佔用線程釋放了鎖,其他線程沒有獲取鎖,那麼當前線程就可以獲取鎖,如果鎖被其他線程佔用,那麼加入到waitset中,排隊,排隊的時候不能獲取鎖,只能等前
線程
,
多線程
一隻魚 -
鎖狀態標識位
鎖升級過程
public static void main(String[] args) throws Exception {
Object lock = new Object();
System.out.println("A---" + ClassLayout.parseInstance(lock).toPrintable());
線程
一隻魚 -
volatile
volatile特性
保證可見性,不保證原子性,
讀寫禁止指令重排序
volatile寫操作之前 StoreStore,寫之後StoreLoad
volatile讀操作之後 LoadLoad LoadStore
為什麼會不一致
1、線程本地內存共享變量的副本讀,沒有立即同步到主內存,出現了可見性問題。主內存是所有線程共享的,每個線程都有工作內存,不共享線程工作時,把
線程
一隻魚 -
AbstractQueuedSynchronizer
抽象隊列同步器
AbstractQueuedSynchronizer是一個模板類,內部包含一些模板方法,該類是一個抽象類,內部包含三個volatile屬性head、tail、state、ownerThread,其中head和tail為Node屬性。
Node是一個內部類,主要包含了waitStatus,prev,next,thread,nextWaiter。子類需要實現tryAcqui
線程
一隻魚 -
Condition
架構圖
sync-queue和condition-queue是相互獨立的,當調用signal方法時,會將等待隊列中的線程喚醒,這個喚醒的線程和普通的線程一樣去爭搶鎖,如果沒有強到,加入到sync-queue,此時節點就從condition-queue加入到了sync-queue,調用signalAll方法,node也是一個一個轉移過去的。
condition-queue中的Node使
線程
一隻魚 -
CountDownLatch
CountDownLatch
CountDownLatch初始化一個state,
調用await方法,如果state=0,那麼獲得鎖,如果state0,那麼加入到等待隊列
調用countDown方法,自旋cas做state-1操作,如果state=0,喚醒等待隊列次頭節點,同時自旋喚醒,被喚醒的線程把次頭節點設置為頭節點,在喚醒次頭節點的線程。由於把次頭節點設置為頭節點這
線程
一隻魚 -
ThreadLocal
四種引用
強引用:直接new一個對象,就是強引用
軟引用:SoftReference,內存不夠的時候,會被垃圾回收
弱引用:WeakReference,發現就回收
虛引用:PlantomReference,虛引用用來管理堆外內存空間,是供jvm使用的,需要和ReferenceQueue關聯,在代碼中定一個虛引用的變量,調用get方法,返回永遠為null
原理
線程
一隻魚 -
ThreadPoolExecutor
基礎
線程池的7個參數,核心線程數,最大線程數,worker生存時間,時間單位,阻塞隊列,ThreadFactory,RejectExecutionHandler拒絕策略
阻塞隊列可以是ArrayBlockingQueue和LinkedBlockQueue,LinkedBlockQueue可以是無界隊列,如果是無界隊列,那麼非核心線程不會創建
自定ThreadFactory可以設置友好的線程
線程
一隻魚 -
內存語義
synchronized內存語義
volatile內存語義
final內存語義
線程