1. 程式人生 > >synchronized 是鎖物件還是鎖程式碼

synchronized 是鎖物件還是鎖程式碼

package java_thread.mysynchronized;


//synchronized    鎖是所物件還是鎖程式碼
//原文:https://www.cnblogs.com/QQParadise/articles/5059824.html   


public class synchronized_test1 {
	//在Java中,synchronized關鍵字是用來控制執行緒同步的,就是在多執行緒的環境下,控制synchronized程式碼段不被多個執行緒同時執行。synchronized既可以加在一段程式碼上,也可以加在方法上。
	//關鍵是,不要認為給方法或者程式碼段加上synchronized就萬事大吉
		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結束..
	        
	        	啟動了三個執行緒,每隔執行緒雖然都有sycn關鍵字   但是鎖得住不是地段程式碼而是當前執行緒test  個個執行緒沒有相同物件的引用所以不會產生預期的效果  
	        */
			
	      /*  Sync sync=new Sync();
	        for(int i = 0; i < 3; i++) {
	        	 //synchronized(Sync.class) {   這種寫法是錯誤的    因為這個鎖需要線上程內才能生效     同理若是這個鎖生效,那實現的情況就是多個執行緒呼叫main這個方法(自己理解,若是錯位,希望各位能夠指正。謝謝!)
	        		Thread thread = new Mythread2(sync);
	        		thread.start();
	        }*/
	        
	        
	        
	       /* 執行結果:
	        test開始..
	        test結束..
	        test開始..
	        test結束..
	        test開始..
	        test結束..
	        
	        	其傳入的是相同的物件      而物件內有相應的物件鎖   所以不能併發操作
	        */
	        
	        //synchronized鎖住的是程式碼還是物件。答案是:synchronized鎖住的是括號裡的物件,而不是程式碼。對於非static的synchronized方法,鎖的就是物件本身也就是this。
	        
	        
	        
	     /*   那麼,如果真的想鎖住這段程式碼,要怎麼做?也就是,如果還是最開始的那段程式碼,每個執行緒new一個Sync物件,怎麼才能讓test方法不會被多執行緒執行。 

	        解決也很簡單,只要鎖住同一個物件不就行了。例如,synchronized後的括號中鎖同一個固定物件,這樣就行了。這樣是沒問題,但是,比較多的做法是讓synchronized鎖這個類對應的Class物件。
	        
	        *
	        */
			
			for (int i = 0; i < 3; i++) {  
	            Thread thread = new Mythread3();  
	            thread.start();  
	        }
			
			
	    }  
}


class MyThread extends Thread {  
    public void run() {  
        Sync sync = new Sync();  
        sync.test();  
    }  
}  
 

class Sync{
	public  void test() {  
        System.out.println("test開始..");  
        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("test結束..");  
    }  
}

class Mythread2 extends Thread{
	private Sync sycn2;
	public Mythread2(Sync sycn2) {
		this.sycn2=sycn2;
	}
	public void run() {
		synchronized(Sync.class) {
		sycn2.test();
		 }
	}
}


class Mythread3 extends Thread{
	
	public void run() {
		Sync sycn2=new Sync();
		synchronized(Sync.class) {
		sycn2.test();
		 }
	}
}

//原文:https://www.cnblogs.com/QQParadise/articles/5059824.html   

建議各位還是去看看原文章