多執行緒的物件鎖和類鎖

2022-08-22 06:54:11 字數 2747 閱讀 1927

今天面試官問了乙個問題,如果在乙個類中的普通方法加上synchronized 關鍵字,兩個執行緒可以同步方法這個方法嗎?為什麼

當時回答是不可以同步,然後面試官確認我說一定嗎?當時就知道回答錯了。

現在實現了下,原來是類鎖和物件鎖的區別所在,也算是普及了下相關知識吧。

類鎖:就是在方法前面加上 static synchronized或者方法裡面 synchronized(mainthings.class) 這兩個寫法,那麼這是乙個類鎖。

物件鎖:就是在方法前面加上synchronized或者方法裡面 synchronized(this) 這兩個寫法,那麼這是乙個類鎖。

結論:如果是物件鎖的話,兩個執行緒可以同時訪問同乙個方法。

如果是類鎖的話,兩個執行緒是不可以同時訪問同乙個方法,當前執行緒會將另外乙個執行緒阻塞起來,等當前執行緒處理完了釋放了當前鎖後才可以進來。

原因:物件鎖-》面對每乙個物件來說,都有各自的鎖,每個執行緒訪問不同物件時都可以擁有自己的鎖,所以不會造成這個執行緒的物件被另乙個物件上鎖。

類鎖-》對每個執行緒來說,只有一把鎖,誰先擁有這把鎖,誰先訪問,其他執行緒阻塞,等當前訪問完了的執行緒釋放鎖後,其他執行緒才可以訪問。

public class dothing1 implements runnable

@override

public void run()

public class dothing2 implements runnable

@override

public void run()

public class dothing2 implements runnable

@override

public void run()

主類:public class mainthings

/*** @param args

*/public static void main(string args)

/**

* @param args

*/public static void main(string args) {

// todo auto-generated method stub

mainthings mainthings=new mainthings();

mainthings mainthings2=new mainthings();

dothing1 do1=new dothing1(mainthings);

dothing2 do2=new dothing2(mainthings2);

thread t1=new thread(do1);

thread t2=new thread(do2);

t1.start();

t2.start();

執行結果:

thread-0 dothing1 is begin

this isthread-0 entry

this isthread-0 out

thread-1 dothing2 is begin

this isthread-1 entry

this isthread-1 out

假設方法a和b是在同乙個類test中的兩個方法。

test t=new test();

t.methodb();

這個時候,methodb方法被呼叫時,因為加了synchronized ,需要先獲得乙個鎖,這個鎖的物件應該是t,也就是當前的這個test類的例項,而獲得鎖的東西是執行緒,也就是說當前執行緒拿到了t的鎖(而不是你說的b方法獲得鎖),這個時候b方法內呼叫methoda,因為a也加了synchronized,也需要獲得乙個鎖,因為a和b都是test類中的方法,所以當前執行緒要獲得的鎖的物件也是t。由於當前執行緒在執行b方法時已經持有了t物件的鎖,因此這時候呼叫methoda是沒有任何影響的,相當於方法a上沒有加synchronized。

另一種情況:假設現在有兩個test類

test t1=new test();

test t2=new test();

t1.methodb();//此時當前執行緒持有了t1物件的鎖

t2.methodb();//此時當前執行緒也持有了t2物件的鎖

當前執行緒持有了兩把鎖,鎖的物件分別是兩個不同的test類的例項t1和t2,互相沒有影響。

再一種情況:假設在多執行緒環境下,兩個執行緒都可以訪問test t=new test();

此時假設thread1裡呼叫t.methodb();同時thread2裡呼叫t.methodb()

這時假設thread1先搶到t物件的鎖,那麼thread2需要等待thread1釋放t物件的鎖才可以執行b方法。

結果像這樣:

thread1獲得t的鎖--thread1執行methodb--thread1執行methoda--釋放t的鎖---thread2獲得t的鎖--thread2執行methodb--thread2執行methoda--釋放t的鎖。

synchronized還有很多種使用方法,但只有明白是那條執行緒獲得哪個物件的鎖,就很容易明白了

Java多執行緒 類鎖和物件鎖

我們設想某個執行緒獨佔某個類,必須執行完才能再次建立物件 預期輸出以下結果 物件鎖示例 關鍵字synchronized取得的鎖都是物件鎖,而不是把一段 方法 當做鎖,所以 中哪個執行緒先執行synchronized關鍵字的方法,哪個執行緒就持有該方法所屬物件的鎖 lock 在靜態方法上加synchr...

多執行緒的補充 關於類鎖和物件鎖的理解

鎖什麼時候需要使用?概述 每個類建立的物件都對應一把鎖,如果是多個執行緒訪問不同物件的時候,其它執行緒不用等待鎖的釋放,因為它們是不同的鎖。請看 public class test class mythread implements runnable 重寫run方法 public void run ...

多執行緒 互斥物件和鎖

互斥物件的主要操作有兩個,即加鎖 lock 和解鎖 unlock 當乙個執行緒對互斥物件進行lock操作並成功獲得這個互斥物件的所有權,在此執行緒對此物件unlock前,其他執行緒對這個互斥物件的lock操作都會被阻塞。有些傾向需要對多個互斥物件進行加鎖,考慮下面的 std mutex mt1,mt...