多執行緒(進階)
1、基礎
2、執行緒和程序:
1.執行緒六個狀態:
還有一個"終止"
2.wait和sleep的區別:
3、Lock鎖(重點)
傳統 Synchronized:
不公平鎖
Lock介面:
公平鎖:十分公平:可以先來後到非公平鎖:十分不公平:可以插隊 (預設)
Synchronized 和 Lock 區別:
1、 Synchronized 內建的Java關鍵字, Lock 是一個Java類
2、 Synchronized 無法判斷獲取鎖的狀態,Lock 可以判斷是否獲取到了鎖
3、 Synchronized 會自動釋放鎖,lock 必須要手動釋放鎖!如果不釋放鎖,死鎖
4、 Synchronized 執行緒 1(獲得鎖,阻塞)、執行緒2(等待,傻傻的等);Lock鎖就不一定會等待下去;
5、 Synchronized 可重入鎖,不可以中斷的,非公平;Lock ,可重入鎖,可以 判斷鎖,非公平(可以自己設定);
6、 Synchronized 適合鎖少量的程式碼同步問題,Lock 適合鎖大量的同步程式碼!
4、生產者和消費者問題
面試的:單例模式、排序演算法、生產者和消費者、死鎖
生產者和消費者問題 Synchronized 版
解決if用While
5.lock與Synchronized對應的方法:
Synchronized:
(重):
- 多個執行緒用同一個對像,呼叫同一個類被Synchronized鎖的方法,變數,執行緒都只能一個一個來呼叫!
-
多個執行緒如果用的是不同對像(不同的類),呼叫被Synchronized鎖的方法,變數,執行緒不相干擾!
static修飾的概念是類的模板,任何類還沒載入就要先載入類它的模板,類的模板只有一個。
如果被static(靜態修飾),就算用不同的物件(名字)宣告,static修飾的都是指向它唯一的類模板,只能一個一個呼叫!
6、Condition的使用
lockd等待,喚醒方法:
condition1.signal();喚醒condition1
Lock-精準喚醒:
7、List的安全
List<String> list = new CopyOnwriteArrayList<>();
8、Set的安全
Set<string> set = new CopyOnwriteArrayset<>();
9、map的安全
Collections.synchronizedMap(Map<K,V> m) )可以代替HashMap,但是它們都是通過使用一個全域性的鎖來同步不同執行緒間的併發訪問,因此會帶來不可忽視的效能問題。
Map<string, string> map = new ConcurrentHashMap<>();
ConcurrentHashMap是J.U.C(java.util.concurrent包)的重要成員,它是HashMap的一個執行緒安全的、支援高效併發的版本。在預設理想狀態下,ConcurrentHashMap可以支援16個執行緒執行併發寫操作及任意數量執行緒的讀操作。本文將結合Java記憶體模型,分析JDK原始碼,探索ConcurrentHashMap高併發的具體實現機制,包括其在JDK中的定義和結構、併發存取、重雜湊和跨段操作,並著重剖析了ConcurrentHashMap讀操作不需要加鎖和分段鎖機制的內在奧祕和原理。
11、常用輔助類
CountDownLatch
執行緒減法計數器
CyclicBarrier
執行緒加法計數器
Semaphore
12、讀寫鎖
使用
沒有加鎖時:
結果
讀鎖和寫鎖
又名(獨佔鎖和共享鎖)
結果
總結
13、阻塞佇列
佇列和阻塞
BlockingQueue
總
1、丟擲異常:
2、返回Boolean值
3、一直阻塞
4、超時等待
14、同步佇列
SynchronousQueue
BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); //同步佇列
結果:
總結
15、執行緒池
Executors執行緒池
Executors執行緒池三大方法
1、單個執行緒池
2、固定執行緒池
3、可伸縮執行緒池
三大方法本質
ThreadPoolExecutor
1、阿里巴巴規範手冊說明
2、ThreadPoolExecutor七大引數
2、ThreadPoolExecutor四種拒接策略
1、
2、
3、
4、
池大小設定優化
1、CPU密集型
2、IO密集型
16、四大函式式介面
1、Function函式式介面
還能把括號去掉
2、斷定型介面
3、Consumer消費型介面
4、 Supplier供給型介面
17、Stream流式計算(1.8新特性)
18、ForkJoin
1、ForkJoin的特點:工作竊取
雙端佇列
2、使用和對比
使用三種方法計算1+到10億的值
1、普通For迴圈
2、ForkJoin
2.1、編寫計算類
2.2、建立ForkJoin工廠執行計算
3、Stream流式計算
一行程式碼
4、結果
19、非同步回撥
CompletableFuture
1、沒有返回值()
2、有返回結果(supplyAsync)
20、JMM
JMM的八種指令
21、Volatile
1、保持可見性
快取鎖:
匯流排加鎖
快取一致性協議
2、不保證原子性
如:多執行緒呼叫num++;
除了加鎖lock和synchronized還有原子類可以保證原子性
原子類CAS
實現
3、避免指令重排
Volatile的實現
(2)禁止指令重排底層原理:
volatile實現禁止指令重排優化,從而避免多執行緒環境下程式出現亂序執行的現象。
先了解下概念,記憶體屏障(Memory Barrier)又稱記憶體柵欄,是一個CPU指令,它的作用有兩個:
保證特定操作執行的順序性;
保證某些變數的記憶體可見性(利用該特性實現volatile記憶體可見性)
volatile實現禁止指令重排優化底層原理:
由於編譯器和處理器都能執行指令重排優化。如果在指令間插入一條Memory Barrier則會告訴編譯器和CPU,不管什麼指令都不能和這條Memory Barrier指令重排,也就是說通過插入記憶體屏障,就能禁止在記憶體屏障前後的指令執行重排優化。記憶體屏障另外一個作用就是強制刷出各種CPU的快取資料,因此任何CPU上的執行緒都能讀取到這些資料的最新版本。
左邊:寫操作場景:先LoadStore指令,後LoadLoad指令。
右邊:讀操作場景:先LoadLoad指令,後LoadStore指令。
22、單例模式
概念:
java中單例模式是一種常見的設計模式,單例模式的寫法有很多種,比較常見的有三種:懶漢式、餓漢式、內部類、雙重驗證。
單例模式有以下特點:
1、單例類只能有一個例項(new 的物件)。
2、單例類必須自己建立自己的唯一例項。
3、單例類必須給所有其他物件提供這一例項。
單例模式確保該類只被是例項化一次,並且只能自己例項化自己。
若想某一類不在類外被例項化,只需用private修飾符修飾其建構函式。
1、餓漢式
2、懶漢式
3、靜態內部類式
23、深入理解CAS
AtomicInteger
1、Unsafe類
ABA問題
通俗來講就是你大爺還是你大爺,你大媽已經不是你大媽了^_^(他已經被動過了)
程式碼實現
解決辦法
如果執行緒one操作不被中斷,那麼問題就解決了
- 將類變成原子類
- 操作過程新增版本號
即為下面的原子引用!
24、原子引用
AtomicStampedReference
但是Integer型別的範圍是-128~127,超出範圍會在堆裡面新建一個物件並不會複用物件
你自己看一下原始碼compareAndSet原始碼,底層是用==進行判斷
帶版本號的原子類
它被人動過,版本號就不是原來的版本號了
25、各種鎖的理解
1、公平鎖和非公平鎖
2、可重入鎖
(遞迴鎖)
可重入鎖是指:某個執行緒已經獲取了某個鎖,那麼他可以再次獲取該鎖而不陷入死鎖
總結下:什麼是 "可重入",可重入就是說某個執行緒已經獲得某個鎖,可以再次獲取鎖而不會出現死鎖。
3、自旋鎖
4、死鎖
解開死鎖,避免死鎖產生的條件就可以了
26、ThreadLocal的原理和使用場景
區別: