android studio 警告 synchronization on non-final field


測試代碼如下:

 

 1 public class SyncNonFinalField {
 2     private Object object = new Object();
 3     public void start() {
 4         
 5         new Thread(new Runnable() {
 6             
 7             @Override
 8             public void run() {
 9                 System.out.println("線程1等待鎖");
10                 synchronized (object) {
11                     System.out.println("線程1獲取到了鎖");
12                     object = new Object();
13                     System.out.println("線程1准備sleep");
14                     try {
15                         Thread.sleep(5000L);
16                     } catch (InterruptedException e) {
17                         e.printStackTrace();
18                     }
19                     System.out.println("線程1 sleep結束");
20                 }
21             }
22         }).start();
23         
24         new Thread(new Runnable() {
25             
26             @Override
27             public void run() {
28                 try {
29                     Thread.sleep(1000L);
30                 } catch (InterruptedException e) {
31                     e.printStackTrace();
32                 }
33                 System.out.println("線程2等待鎖");
34                 synchronized (object) {
35                     System.out.println("線程2獲取到了鎖");
36                 }
37             }
38         }).start();
39     }
40 }

 

 

 

輸出結果:

線程1等待鎖
線程1獲取到了鎖
線程1准備sleep
線程2等待鎖
線程2獲取到了鎖
線程1 sleep結束
 
也就是說,在線程1的同步塊中,只要一給object重新賦值,線程2立即就進入到了同步塊中
 
分析:
synchronized (object) 鎖的是object這個引用所指向的對象,而不是鎖引用。
線程1 sleep 時,並沒有釋放舊對象的鎖。
但它讓 object 指向了一個新對象之后,線程2就立即獲取到了新對象的鎖,所以線程2進入到了同步塊中。
 
解決辦法:
用final修飾object,避免它在同步塊中被重新賦值。


免責聲明!

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



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