深入講解Java多線程的synchronized的類鎖和對象鎖

先來看個概念:

多個線程多個鎖:多個線程,每個線程都可以拿到自己指定的鎖,分別獲得鎖之後,執行synchronized方法體的內容。

Demo演示

按照正常邏輯來看的話,結果會輸出:

tag a ...

tag a, num = 100

tag b ...

tag b, num = 200

因為我們在printNum方法前面加了synchronized,保證同步性。

但是結果卻輸出如下:

tag a ...

tag b ...

tag b, num = 200

tag a, num = 100

為什麼呢?

結果分析:

關鍵字synchronized取得的鎖都是對象鎖,而不是把一段代碼(方法)當作鎖,所以示例代碼中的那個線程先執行synchronized關鍵字的方法,那個線程就持有該方法所屬對象的鎖(Lock),兩個對象,線程獲得的就是兩個不同的鎖,他們互不影響。

Advertisements

有一種情況是所有對象都是相同的鎖, 即在靜態方法上加synchronized關鍵字,表示鎖定.class類,類一級別的鎖(獨佔.class類)。

所以很明顯了,

final MultiThread m1 = new MultiThread();final MultiThread m2 = new MultiThread();

這是兩個不同的對象,所以擁有不同的鎖,各自鎖各自的,互不相干。所以執行結果順序也是混亂的。

解決方案:

給方法加static,讓他鎖上整個類,static方法是類獨有,而不是對象,這樣就是synchronized的.class類,所有對象都擁有共同的鎖。

Advertisements

你可能會喜歡