1. 程式人生 > 其它 >JUC 之多執行緒鎖的 8 個問題分析

JUC 之多執行緒鎖的 8 個問題分析

1. 程式程式碼

 
package com.atguigu.thread;import java.util.concurrent.TimeUnit;class Phone{
public synchronized void sendSMS() throws Exception{System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception{System.out.println("------sendEmail");
}
public void getHello(){System.out.println("------getHello");
}
}/**** @Description: 8鎖* @author xialei*1 標準訪問,先列印簡訊還是郵件2 停4秒在簡訊方法內,
先列印簡訊還是郵件3 新增普通的hello方法,是先打簡訊還是hello4 現在有兩部手機,先列印簡訊還是郵件5 
兩個靜態同步方法,1部手機,先列印簡訊還是郵件6 兩個靜態同步方法,2部手機,先列印簡訊還是郵件7 1個靜態
同步方法1個普通同步方法,1部手機,先列印簡訊還是郵件8 1個靜態同步方法1個普通同步方法,2部手機,
先列印簡訊還是郵件* ---------------------------------**/
public class Lock_8{public static void main(String[] args) throws Exception{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {try {phone.sendSMS();
} catch (Exception e) {e.printStackTrace();
}
}, "AA").start();Thread.sleep(100);new Thread(() -> {
try {phone.sendEmail();
//phone.getHello();
//phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
 

2. 鎖的 8 個問題

(1) 標準訪問,先列印簡訊還是郵件

(2) 停 4 秒在簡訊方法內,先列印簡訊還是郵件

(3) 普通的 hello 方法,是先打簡訊還是 hello

(4) 現在有兩部手機,先列印簡訊還是郵件

(5) 兩個靜態同步方法,1 部手機,先列印簡訊還是郵件

(6) 兩個靜態同步方法,2 部手機,先列印簡訊還是郵件

(7) 1 個靜態同步方法,1 個普通同步方法,1 部手機,先列印簡訊還是郵件

(8) 1 個靜態同步方法,1 個普通同步方法,2 部手機,先列印簡訊還是郵件

3. 鎖的 8 個問題分析

一個物件裡面如果有多個 synchronized 方法,某一個時刻內,只要一個執行緒去呼叫其中的一個 synchronized 方法了,其它的執行緒都只能等待,換句話說,某一個時刻內,只能有唯一一個執行緒去訪問這些 synchronized 方法。

鎖的是當前物件 this,被鎖定後,其它的執行緒都不能進入到當前物件的其它的 synchronized 方法。

加個普通方法後發現和同步鎖無關。

換成兩個物件後,不是同一把鎖了,情況立刻變化。

synchronized 實現同步的基礎:Java 中的每一個物件都可以作為鎖。

具體表現為以下 3 種形式。

對於普通同步方法,鎖是當前例項物件。

對於靜態同步方法,鎖是當前類的 Class 物件。

對於同步方法塊,鎖是 Synchonized 括號裡配置的物件

當一個執行緒試圖訪問同步程式碼塊時,它首先必須得到鎖,退出或丟擲異常時必須釋放鎖。

也就是說如果一個例項物件的非靜態同步方法獲取鎖後,java培訓

該例項物件的其他非靜態同步方法必須等待獲取鎖的方法釋放鎖後才能獲取鎖,可識別的例項物件的非靜態同步方法因為跟該例項物件的非靜態同步方法用的是不同的鎖,所以毋須等待該例項物件已獲取鎖的非靜態同步方法釋放鎖就可以獲取他們自己的鎖。

所有的靜態同步方法用的也是同一把鎖——類物件本身,這兩把鎖是兩個不同的物件,所以靜態同步方法與非靜態同步方法之間是不會有競態條件的。但是一旦一個靜態同步方法獲取鎖後,其他的靜態同步方法都必須等待該方法釋放鎖後才能獲取鎖,而不管是同一個例項物件的靜態同步方法之間,還是不同的例項物件的靜態同步方法之間,只要它們同一個類的例項物件!