深入講解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類,所有對象都擁有共同的鎖。