用synchronized關鍵字加鎖

官方介紹synchronized作用:

   同步方法支持一種簡單的策略來防止線程干擾和內存一致性錯誤:如果一個對象對多個線程可見,則用改對象變量的所有讀取或寫入都是通過同步方法完成的。

一句話來說:

能夠保證一段時間內只有一個線程執行該段代碼,以達到併發安全的效果,是一種悲觀鎖。

 

看2段代碼:

    

	public static void main(String[] args) {
			  for (int i = 0; i <2; i++) {
				  DoThreads dt = new DoThreads(0);
				  Thread dothread = new Thread(dt);
				  dothread.start();
			}
			
		}

public class DoThreads implements Runnable {
	
		private static   int money;
		
		private static final Object  o = new Object();
		public DoThreads(int ages) {
			super();
			this.money = money;
		}
	
		@Override
		public void run() {
			testMethod();
			
		}
			
		public  void testMethod(){
			for (int i = 0; i < 1000; i++) {
				 try {
						Thread.sleep(3);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				 money=money+10;
			}
		
	
			System.out.println(Thread.currentThread().getName()+"開始"+"===金額"+money);
			 try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(Thread.currentThread().getName()+"結束"+"===金額"+money);
		 
	}
}

輸入結果爲:

Thread-0開始===金額19870
Thread-1開始===金額19920
Thread-0結束===金額19920
Thread-1結束===金額19920

 

說明2個線程工作的時候金額髮生了串號的錯誤。我們想要的結果是最後金額20000

 

這個時候我們的synchronized該上場了~

 

synchronized有2種用法:

1.對象鎖

   包括方法鎖和同步代碼塊鎖
 

同步代碼塊鎖:

       synchronized(this){

         需要同步的代碼

}

Object  o = new Object();

    synchronized(o){

         需要同步的代碼

     }

方法鎖:

   public synchronized void testMethod(){

}

2.類鎖

   包括修飾靜態方法和鎖class對象或靜態object對象

   修飾靜態方法:

public static synchronized void testMethod(){

 需要鎖代碼 

}

鎖class對象或靜態object對象

synchronized (DoThreads.class) {

}

 static Object  o = new Object();

    synchronized(o){

         需要同步的代碼

     }

 

synchronized有2種用法介紹:

多線程執行同一任務對象,使用對象鎖和類鎖都能保證線程安全。

多線程執行不同任務對象,使用對象鎖不能保證線程安全,使用類鎖可以保證線程安全。

synchronize的性質

1 .可重入性

同一個線程的外層方法獲得鎖之後,內層方法可以直接再次獲取該鎖

優點 ps:避免死鎖  提高封裝性

 2 .不可中斷性

 一旦同一個鎖被別人獲得,只能等待別的線程釋放該鎖才能獲得,如果別人不釋放,只能永遠等下去。

 

synchronize缺陷

1.效率低

2.不夠靈活

3.無法知道是否成功獲得鎖

 

建議使用原則

能用工具包實現就不用synchronize;

能用synchronize實現就用synchronize;

最後再選擇lock鎖。

使用注意點:

鎖對象不能爲空,作用域不宜過大,避免死鎖

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章