深入理解synchronized方法同步的是方法還是物件?
阿新 • • 發佈:2018-12-15
一.運用synchronized關鍵字
首先我們來看看一個多執行緒中執行緒不安全的列子
程式碼如下:
共享資料類:
public class NotSynchronizated extends Thread { private int num =10; @Override public void run(){ try { System.out.println("當前執行緒為:"+currentThread().getName()); num--; System.out.println("num的值為:"+num); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }
執行緒測試類:
public class Text { public static void main(String[] args) { //將共享資料放入3個執行緒裡進行處理 NotSynchronizated notSynchronizated = new NotSynchronizated(); Thread t1=new Thread(notSynchronizated,"A"); Thread t2=new Thread(notSynchronizated,"B"); Thread t3=new Thread(notSynchronizated,"C"); Thread t4=new Thread(notSynchronizated,"D"); t1.start(); t2.start(); t3.start(); t4.start(); } }
在這個列子中run方法沒有使用關鍵字synchronized,那麼就會造成執行緒不安全,結果如下:
那麼當我們使用關鍵字synchronized後結果就會同步了,結果如下:
那麼,在這裡是對這個run方法進行了同步呢?還是對這個物件進行了同步呢?
二.synchronized同步的是物件
為了證明synchronized同步的是物件,我們舉出下面的程式碼:
共享資源類:
public class SynchronizatedObject extends Thread { private int num=20; @Override public synchronized void run(){ System.out.println("當前的執行緒為"+currentThread().getName()); num--; System.out.println("當前num為"+num); } }
測試類:
public class Text { public static void main(String[] args) { SynchronizatedObject synchronizatedObject1=new SynchronizatedObject();//建立第一個資源共享類 SynchronizatedObject synchronizatedObject2=new SynchronizatedObject();//建立第二個資源共享類 Thread t1=new Thread(synchronizatedObject1,"A");//加入 Thread t2=new Thread(synchronizatedObject2,"B");//加入 t1.start(); t2.start(); } }
結果如下:
從這裡明顯看出這個synchronized關鍵字同步的是物件而不是方法,
如果同步的是方法那麼他將不會出現這種執行緒不安全的情況,而是兩物件一個一個按順序的進入這個同步的方法裡,
出現這中情況,只能說明他是物件同步的。
所以說這段程式碼意思是我建立了兩個物件,同時我也建立了兩把物件鎖來同步話各自的run方法,只不過每一條執行緒的呼叫順序不同才會出現這樣的結果。
總結:synchronized關鍵字同步的是物件不是方法