Java內部鎖(synchronized)中類鎖和物件鎖
阿新 • • 發佈:2018-11-05
版權宣告:本文為博主原創文章,轉載請註明出處。 https://blog.csdn.net/qq_25827845/article/details/77688880
synchronized是Java提供的內部鎖,裡邊有類鎖和物件鎖;在靜態方法中,我們一般使用類鎖,在例項方法中,我們一般使用物件鎖,接下來,分析類鎖和物件鎖的區別和聯絡。
1、兩個同步塊使用同一個物件鎖:
public class Main { static Main objMain = new Main(); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { Main.method2(); } }).start(); new Thread(new Runnable() { @Override public void run() { Main obj = new Main(); obj.method(); } }).start(); } public static void method2() { synchronized (objMain) { System.out.println("method2......"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("method2....666.."); } } public void method(){ synchronized (objMain) { System.out.println("method..."); } } }
我們在main方法中啟動兩個執行緒,分別執行method2和method方法;結果顯示,當前輸入在method2先佔有物件鎖之後,method方法內部將得不到該objMain物件鎖,直到method2中執行結束。method方法中才會執行同步塊。
說明:兩個不同的執行緒在搶佔同一個物件鎖。
2、如果我們讓兩個同步塊一個使用類鎖一個使用物件鎖:
public class Main { static Main objMain = new Main(); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { Main.method2(); } }).start(); new Thread(new Runnable() { @Override public void run() { Main obj = new Main(); obj.method(); } }).start(); } public static void method2() { synchronized (Main.class) { System.out.println("method2......"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("method2....666.."); } } public void method(){ synchronized (objMain) { System.out.println("method..."); } } }
此時,並不會出現鎖互斥的現象,即不同的執行緒之間沒有鎖的爭用。
3、如果我們將同步塊中的鎖均設定為類鎖,即Main.class
此時,情況和1中一樣,兩個執行緒爭用鎖,一個沒有釋放鎖,另一個執行緒的同步塊將不會被執行。(因為此時兩個執行緒使用了同一個類鎖Main.class)
4、兩個同步塊中使用不同的類鎖,比如一個為Main.class,另一個為Object.class。
此時,是兩把不同的類鎖,不會導致執行緒之間的鎖爭用,即自己執行自己的同步塊即可。
5、同理,兩個同步塊中使用不同的物件鎖,也不會導致鎖爭用,執行緒之間相互獨立執行。
以上就是對synchronized中類鎖和物件鎖的理解,以及什麼情況下會導致執行緒之間對鎖發生爭用