我已經開始深入學習線程,并在嘗試理解我編寫以下代碼的概念的同時,我不確定代碼的輸出。以下是我編寫的代碼,public class UnsafeCheck extends Thread { private static Person person; // This method is not thread safe without synchronization. Make the method // synchronized to make the code thread safe. public synchronized Person getPerson() { if(person == null) { System.out.println("Inside if block"); person = new Person("Kilarapu Yethendra", 27); } return person; } public void run() { System.out.println("thread's run method"); getPerson(); } public static void main(String[] args) { UnsafeCheck uc = new UnsafeCheck(); uc.start(); UnsafeCheck uc1 = new UnsafeCheck(); uc1.start(); UnsafeCheck uc2 = new UnsafeCheck(); uc2.start(); } }輸出:線程的運行方法內部 if 塊線程的運行方法內部 if 塊線程的運行方法內部 if 塊如果我們觀察到線程 uc 所做的輸出更改并沒有反映在線程 uc1 中,這就是為什么每個線程控制都轉到 if 塊的原因。我期望在 uc1 執行 run 方法時初始化 person 引用,但是對于 uc1 線程來說 person 仍然為空。我所做的一個更有趣的觀察是,如果我將 getPerson() 方法設為靜態,我將按預期獲得輸出。以下是 getPerson() 方法為靜態時的輸出。輸出:線程的運行方法內部 if 塊線程的運行方法線程的運行方法。請幫助我理解流程。
2 回答
函數式編程
TA貢獻1807條經驗 獲得超9個贊
將您的方法聲明為
public synchronized Person getPerson()
意味著它使用包含UnsafeCheck實例(即this)作為監視器來同步訪問。當您創建三個不同的UnsafeCheck實例時,每個實例都有自己的鎖,并且代碼不會按照您的預期執行。
和
public static synchronized Person getPerson()
使用的監視器對于所有實例都是相同的,即UnsafeCheck.class,您會獲得正確的static Person變量同步。
有關synchronized方法的更多信息,請查看 Oracle 的教程:同步方法。
Cats萌萌
TA貢獻1805條經驗 獲得超9個贊
好的,現在我知道你在做什么了,標題有誤導性。監視器的同步關鍵字以對象方式鎖定它,因此只有一個線程可以進入方法 PER Object。
你可以做兩件事來讓它廣泛應用:
1.使 getPerson 方法靜態(它將在應用程序范圍內同步)
2.使用同步塊,允許您選擇同步對象(通?!皌his”用于對象同步,“UnsafeCheck.class”用于應用程序范圍)
添加回答
舉報
0/150
提交
取消
