1. 程式人生 > >Java內部鎖(synchronized)中類鎖和物件鎖

Java內部鎖(synchronized)中類鎖和物件鎖

版權宣告:本文為博主原創文章,轉載請註明出處。 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中類鎖和物件鎖的理解,以及什麼情況下會導致執行緒之間對鎖發生爭用