多執行緒8

chaoshang8發表於2024-09-05

public static void main(String[] args) {
for(int i = 0; i 2; i++) {
new Thread(() - {
System.out.println(Thread.currentThread().getName() + "..." + "aaa");
System.out.println(Thread.currentThread().getName() + "..." + "ccc");
}).start();
}
// 執行過程分兩部分:
// · new Thread(),這行程式碼執行完意味著在程序中開闢了一條新的程式執行路徑
// · start(),執行緒開始執行執行緒任務
// 分析這段程式碼的目的是為了建立意識:執行緒任務再怎麼複雜,都不用管,那是各個執行緒的內部問題,與main執行緒無關
}

192.使用javap反編譯帶有synchronized的class檔案,反編譯生成的檔案中有兩條位元組碼指令monitorenter和monitorexit(位元組碼指令的助記符),透過這兩條位元組碼指令來保證原子性,因此說synchronized的實現是屬於jvm層面的,而Lock的實現屬於Java API層面的

193.synchronized 修飾的方法並沒有 monitorenter 指令和 monitorexit 指令,而是透過 ACC_SYNCHRONIZED 標識,該標識指明瞭該方法是一個同步方法。JVM 透過該 ACC_SYNCHRONIZED 訪問標誌來辨別一個方法是否宣告為同步方法,從而執行相應的同步呼叫

194.synchronized塊和synchronized方法的jvm實現
· synchronized塊的jvm實現是透過兩個jvm位元組碼指令 monitorexit 和 monitorexit
· synchronized方法的jvm實現是透過ACC_SYNCHRONIZED標識

195.AQS 核心思想是,如果被請求的共享資源空閒,則將當前請求資源的執行緒設定為有效的工作執行緒,並且將共享資源設定為鎖定狀態;如果被請求的共享資源被佔用,那麼就需要一套執行緒阻塞等待以及被喚醒時鎖分配的機制,這個機制 AQS 是用 CLH 佇列鎖實現的,即將暫時獲取不到鎖的執行緒加入到佇列中

196.juc包中的ReentrantLock、CountDownLatch、Semaphore都是基於AQS來實現的,定義一個內部類繼承AQS,並根據具體的需求重寫AQS的相關方法

197.synchronized的本質是一把悲觀鎖,因此為了提高效率,引入了CAS,CAS是一種樂觀鎖機制,CAS也是整個juc包實現的基石

198.CAS存在的問題,ABA問題

199.CAS自身原子性的實現原理,也是面試中可能會問到的一個問題(CPU層面保證原子性)

200.ThreadLocal的官方解釋,ThreadLocal類用來提供執行緒內部的區域性變數,這種變數在多執行緒環境下訪問(透過get和set方法訪問)時能保證各個執行緒的變數相對獨立於其他執行緒內的變數,ThreadLocal例項通常來說都是private static 型別的,用於關聯執行緒和執行緒上下文

201.獲取執行緒狀態:Thread t = new Thread(); System.out.println(t.getState());

203.使用 synchronized 加鎖的本質是修改物件的MarkWord

204.多執行緒三大特性:原子性、可見性、有序性

205.JDK1.5之前 synchronized 必須透過作業系統,因此效率低 --馬士兵

206.解決 CAS 的 ABA 問題很簡單,加版本號就可以

207.CAS 的全稱有的叫 CompareAndSet,有的叫 CompareAndSwap,其實都是一個意思

208.CAS 的底層實現是一條彙編指令 lock comxchg

209.執行緒池七個引數
1)corePoolSize 執行緒池核心執行緒數量
2)maximumPoolSize 執行緒池最大執行緒數量
3)keepAliveTime 非核心執行緒存活時間
4)unit 非核心執行緒存活時間單位
5)workQueue 工作佇列
· ArrayBlockingQueue:基於陣列的有界阻塞佇列
· LinkedBlockingQuene:基於連結串列的無界阻塞佇列
· SynchronousQuene:一個不快取任務的阻塞佇列
· PriorityBlockingQueue:具有優先順序的無界阻塞佇列
6)threadFactory:執行緒工廠,建立一個新執行緒時使用的工廠,可以用來設定執行緒名、是否為daemon執行緒等
7)handler 拒絕策略
· CallerRunsPolicy:在呼叫者執行緒中直接執行被拒絕任務的run方法,除非執行緒池已經shutdown,則直接拋棄任務
· AbortPolicy:直接丟棄任務,並丟擲RejectedExecutionException異常
· DiscardPolicy:直接丟棄任務,什麼都不做
· DiscardOldestPolicy:拋棄進入佇列最早的那個任務,然後嘗試把這次拒絕的任務放入佇列

210.對volatile保證可見性和有序性的完整表述
1)保證執行緒可見性(透過快取一致性協議實現)
2)禁止指令重排序(透過記憶體屏障實現)

211.java.util.concurrent.atomic包底層都是基於CAS來實現的

212.sun.misc.Unsafe類的作用
1)直接操作記憶體:allocateMemory()、freeMemory()、pageSize()
2)直接生成類例項:allocateInstance()
3)直接操作類或例項變數:objectFieldOffset()、getInt()、getObject()
4)CAS相關操作:compareAndSwapObject()、compareAndSwapInt()、compareAndSwapLong()

213.同步容器的概念:支援多個執行緒同時往容器中新增元素,支援多個執行緒同時從容器中獲取元素,具備這樣的特性的容器稱為同步容器

214.關於 Callable、Future、FutureTask、CompletableFuture
1)Callable:Runnable + result
2)Future:儲存執行的將來才會產生的結果
3)FutureTask:Future + Runnable
4)CompletableFuture:管理多個Future的結果

215.JDK中的執行緒池分兩大類
1)ThreadPoolExecutor
2)ForkJoinPool
· 分解彙總的任務
· 用很少的執行緒可以執行很多的任務(子任務),ThreadPoolExecutor做不到先執行子任務
· 適用CPU密集型

216.ThreadLocal 適用於每個執行緒需要自己獨立的例項且該例項需要在多個方法中被使用,也即變數線上程間隔離而在方法或類間共享的場景

217.CompletableFuture 對 Future 進行了擴充套件,可以透過設定回撥的方式處理計算結果,同時也支援組合操作

218.CountDownLatch 和 CyclicBarrier 的區別
CountDownLatch 和 CyclicBarrier 都有讓多個執行緒等待同步然後再開始下一步動作的意思,有兩個主要區別
1)CountDownLatch 的下一步的動作實施者是主執行緒,CyclicBarrier 的下一步動作實施者是其它執行緒
2)CountDownLatch 具有不可重複性,CyclicBarrier 具有可重複性

219.Executors 是一個建立執行緒池的工具類

220.Java虛擬機器規範定義Java記憶體模型的目的在於遮蔽掉各種硬體和作業系統的記憶體訪問差異,讓Java程式在各種平臺上都能達到一致的記憶體訪問效果

221.無論是透過執行緒池還是 CompletableFuture 開啟新執行緒,最終都是呼叫 Thread 的 start() 方法(已經在 start() 方法中打斷點進行 debug 驗證過)

222.執行緒池和 CompletableFuture 都可以用來開啟新執行緒,不過功能側重點不同
1)執行緒池主要用於併發執行任務,對執行緒數量的控制和複用執行緒提供了很好的支援
2)CompletableFuture 是 Java 8 引入的一個新特性,用於簡化非同步程式設計模型

相關文章