先上結論:
類方法中,synchronized鎖住的是對象this,只有調用同一個對象的方法才需要獲取鎖。同時,同一個對象中所有加了synchronize的方法只能一次調用一個
靜態方法中,synchronized鎖的是整個類對象,類似於(X.class),該類中所有加了synchronized的靜態方法,一次只能調用一個
1 class Sync { 2 3 public synchronized void test() { 4 System.out.println("test開始.."); 5 try { 6 Thread.sleep(1000); 7 } catch (InterruptedException e) { 8 e.printStackTrace(); 9 } 10 System.out.println("test結束.."); 11 } 12 13 public synchronized void test2() { 14 System.out.println("test2開始.."); 15 try { 16 Thread.sleep(800); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 System.out.println("test2結束.."); 21 } 22 } 23 24 class MyThread extends Thread { 25 26 private Sync sync; 27 28 public MyThread(Sync sync) { 29 this.sync = sync; 30 } 31 32 public void run() { 33 sync.test(); 34 } 35 } 36 37 class MyThread2 extends Thread { 38 39 private Sync sync; 40 41 public MyThread2(Sync sync) { 42 this.sync = sync; 43 } 44 45 public void run() { 46 sync.test2(); 47 } 48 } 49 50 public class Main { 51 52 public static void main(String[] args) { 53 Sync sync = new Sync(); 54 Thread thread = new MyThread(sync); 55 Thread thread2 = new MyThread2(sync); 56 thread.start(); 57 thread2.start(); 58 59 } 60 }
運行結果:
test開始..
test結束..
test2開始..
test2結束..
方案是按順序執行的,說明了鎖住的是同一個對象:
main方法換成以下寫法:
1 public static void main(String[] args) { 2 Thread thread = new MyThread(new Sync()); 3 Thread thread2 = new MyThread2(new Sync()); 4 thread.start(); 5 thread2.start(); 6 7 }
結果:
test開始..
test2開始..
test2結束..
test結束..
synchronized沒有起到同步作用,說明不是同一個鎖
靜態方法:
1 class Sync { 2 3 public static synchronized void test() { 4 System.out.println("test開始.."); 5 try { 6 Thread.sleep(1000); 7 } catch (InterruptedException e) { 8 e.printStackTrace(); 9 } 10 System.out.println("test結束.."); 11 } 12 13 public static synchronized void test2() { 14 System.out.println("test2開始.."); 15 try { 16 Thread.sleep(800); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 System.out.println("test2結束.."); 21 } 22 } 23 24 class MyThread extends Thread { 25 26 public void run() { 27 Sync.test(); 28 } 29 } 30 31 class MyThread2 extends Thread { 32 33 public void run() { 34 Sync.test2(); 35 } 36 } 37 38 public class Main { 39 40 public static void main(String[] args) { 41 Thread thread = new MyThread(); 42 Thread thread2 = new MyThread2(); 43 thread.start(); 44 thread2.start(); 45 46 } 47 }
運行結果:
test開始..
test結束..
test2開始..
test2結束..
本文參考了叉叉哥 的博客:Java線程同步:synchronized鎖住的是代碼還是對象
