1. 程式人生 > >java多執行緒之鎖機制一

java多執行緒之鎖機制一

網上看了一篇關於java synchronized關鍵字使用的很好的文章,現將其簡要總結一下,加深理解。

先總結兩個規則:

synchronized鎖住的是括號裡的物件,而不是程式碼。對於非static的synchronized方法,鎖的就是物件本身也就是this。

多個執行緒的synchronized必須鎖住的是同一個物件,才能防止多個執行緒同時執行同一個物件的同步程式碼段。

有兩種方法可以實現多個執行緒鎖住的是同一個物件

1.執行緒中定義相同的成員,成員的值線上程初始化時從外界注入同一個物件。


class Sync  {  
	  
	//寫法一
//	public void test() {  
//	    synchronized(this){  
//	        System.out.println("test開始..");  
//	        try {  
//	            Thread.sleep(1000);  
//	        } catch (InterruptedException e) {  
//	            e.printStackTrace();  
//	        }  
//	        System.out.println("test結束..");  
//	    }  
//	}   
	//寫法二,與寫法一等效,都是鎖住物件sync
	public synchronized void test() {   
	        System.out.println("test開始..");  
	        try {  
	            Thread.sleep(1000);  
	        } catch (InterruptedException e) {  
	            e.printStackTrace();  
	        }  
	        System.out.println("test結束..");   
	}   
}  
  

class MyThread extends Thread {  
	  
    private Sync sync;  
  
    public MyThread(Sync sync) {  
        this.sync = sync;  
    }  
  
    public void run() {  
        sync.test();  
    }  
}  
  
public class Main {  
  
    public static void main(String[] args) {  
        Sync sync = new Sync();  
        for (int i = 0; i < 3; i++) {  
            Thread thread = new MyThread(sync);  
            thread.start();  
        }  
    }  
}  

輸出結果:

test開始..
test結束..
test開始..
test結束..
test開始..
test結束..

分析:3個執行緒MyThread中都定義了成員sync,在初始化執行緒時,給每個執行緒的sync賦予了相同的值,即3個執行緒的sync是同一個例項。啟動3個執行緒以後,synchronized鎖住的其實就是this,在當前demo中指的就是sync例項,3個執行緒的sync是同一個物件,所以3個執行緒中使用的同一個物件鎖,同一時刻只能有一個執行緒進入test同步方法塊。

 

2.使用類對應的Class作為要鎖住的物件,全域性鎖

class Sync {  
	  
    public void test() {  
        synchronized (Sync.class) {  
            System.out.println("test開始..");  
            try {  
                Thread.sleep(1000);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
            System.out.println("test結束..");  
        }  
    }  
}  
  
class MyThread extends Thread {  
  
    public void run() {  
        Sync sync = new Sync();  
        sync.test();  
    }  
}  
  
public class Main {  
  
    public static void main(String[] args) {  
        for (int i = 0; i < 3; i++) {  
            Thread thread = new MyThread();  
            thread.start();  
        }  
    }  
}  

輸出結果:

test開始..
test結束..
test開始..
test結束..
test開始..
test結束..

分析:類對應的Class物件作為鎖的目標,確保鎖住的是同一個物件。

參考:https://www.cnblogs.com/QQParadise/articles/5059824.html