Java synchronized 鎖住的是整個對象還是只有方法


先上結論:

  類方法中,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鎖住的是代碼還是對象

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM