1. 程式人生 > 其它 >011Java併發包011LockSupport

011Java併發包011LockSupport

本文主要學習了LockSupport的原理和相關操作。

1 是什麼

LockSupport是用來建立鎖和其他同步類的基本執行緒阻塞原語,在內部使用一個許可證的概念來實現阻塞和喚醒,每個執行緒都有一個許可證,許可證只有1和0兩個值,預設是0。

LockSupport中的park()和unpark()的作用分別是阻塞執行緒和解除阻塞執行緒,park()方法會在許可證可用時執行,unpark()方法會在許可證不可用時提供許可證。

歸根結底,LockSupport呼叫的Unsafe中的native程式碼。

2 比較

1)使用Object中的wait()方法讓執行緒等待,使用Object中的notify()方法喚醒執行緒。

必須在synchronized內部執行,否則丟擲IllegalMonitorStateException。

必須先執行wait()方法再執行notify()方法,即只能在wait()方法後使用notify()方法喚醒,否則程式將一直等待無法被喚醒。

2)使用Condition的await()方法讓執行緒等待,使用Condition的signal()方法喚醒執行緒。

必須和Lock組隊使用,否則丟擲IllegalMonitorStateException。

只能在wait()方法後使用notify()方法喚醒,否則程式將一直等待無法被喚醒。

3)使用LockSupport的park()方法讓執行緒等待,使用LockSupport的uppark()方法喚醒執行緒。

不需要在任何方法塊內執行,park()方法和uppark()方法都是靜態方法,可以在任何地方執行。

使用順序無要求,即便uppark()方法提前,也能保證park()方法被喚醒。

3 使用

程式碼如下:

 1 public static void main(String[] args) {
 2   Thread a = new Thread(()->{
 3     try {
 4       Thread.sleep(3000);
 5     } catch (InterruptedException e) {
 6       e.printStackTrace();
 7     }
 8     System.out.println(Thread.currentThread().getName() + "-----進入");
9 LockSupport.park(); 10 System.out.println(Thread.currentThread().getName() + "-----執行"); 11 }, "a"); 12 a.start(); 13 Thread b = new Thread(()->{ 14 System.out.println(Thread.currentThread().getName() + "-----進入"); 15 LockSupport.unpark(a); 16 System.out.println(Thread.currentThread().getName() + "-----執行"); 17 }, "b"); 18 b.start(); 19 }

結果如下:

1 b-----進入
2 b-----執行
3 // 等待三秒
4 a-----進入
5 a-----執行

4 總結

LockSuport是一個執行緒阻塞工具類,所有的方法都是靜態方法,可以讓執行緒在任意位置阻塞和喚醒。LockSupport底層呼叫的Unsafe中的native程式碼。

呼叫park()方法,如果憑證為1,則將憑證變成0,同時park()方法立即返回並繼續執行,如果憑證為0則會阻塞,直到unpark()方法執行將憑證從0變為1。

呼叫unpark()方法會將憑證從0變成1,多次呼叫unpark()的結果仍會使得憑證為1,不會導致憑證累加,憑證只有0和1兩種取值。