嗨我對Java很新,現在我正在進入java併發。我對Synchronized方法有點懷疑:我已經看到,我可以在Synchronized方法中使用If else獲得相同的結果,每次都檢查如果執行某個操作的條件已滿足,則可以使用wait/notify方法。等待vs無等待同步方法(java)
因爲我得到了同樣的結果,我想知道如果其他方法有什麼優勢或劣勢而不是等待和通知方法?我認爲效率將是一個缺點,因爲如果總是檢查條件,誰等待只是停下來等待通知。但是還有其他的優點和缺點嗎?
Thx!
嗨我對Java很新,現在我正在進入java併發。我對Synchronized方法有點懷疑:我已經看到,我可以在Synchronized方法中使用If else獲得相同的結果,每次都檢查如果執行某個操作的條件已滿足,則可以使用wait/notify方法。等待vs無等待同步方法(java)
因爲我得到了同樣的結果,我想知道如果其他方法有什麼優勢或劣勢而不是等待和通知方法?我認爲效率將是一個缺點,因爲如果總是檢查條件,誰等待只是停下來等待通知。但是還有其他的優點和缺點嗎?
Thx!
你在混合兩個概念。如果 - 其他與Wait-Notify完全不同。你想要兩個線程與互相通信,每個其他這是其中使用Wait-Notify而if-else是一般條件語句的地方。
你不能有兩個線程只需使用if-else條件相互通信。你可以編寫你的代碼,使它看起來像它一樣,但你只是不允許線程互相交互。
此外,它可能導致不良後果/計算狀態。遲早你會有hotchpotch代碼。
同步塊使代碼線程安全。如果您希望更高效,則您需要使用wait()
和notify()
或notifyAll()
。
例如,如果您的共享資源是一個列表,多個線程共享。如果你把它放在一個監視器的同步塊中,那麼在上下文切換期間,線程將不斷跳入並運行代碼。即使列表是空的!
因此,wait()
用於監視器(synchronized(..)
中的對象),作爲「告知」所有線程冷卻並停止使用CPU週期的機制,直到進一步通知或notifyAll()
。
synchronized(monitor) {
while(list.isEmpty())
monitor.wait();
doSomething(...)
}
在上面的例子中,doSomething()
將被執行僅當列表不爲空,之後另一個線程執行notify()
或notifyAll()
代碼別處。
BUT用下面的代碼:
synchronized(monitor) {
if(!list.isEmpty())
doSomething(...)
}
當線程進來到同步塊中,有3種可能情況:
doSomething()
將會是我不會被執行。doSomething()
可能正確執行,或者...if
之後和doSomething
之前存在上下文切換,並且另一個線程獲取了所有列表項,則另一個上下文切換線程將在空列表上執行doSomethig()
。所以,只是爲了總結一切,如果你使用wait/notify,你保證更有效的代碼!線程無法工作時,他們不需要。
如果另一個線程正確使用'synchronized',場景3就不會發生,因爲這是'synchronized'塊的要點,保證其他線程不會產生干擾。另一方面,如果其他線程不能正確使用'synchronized',它也會打破基於循環的代碼,因爲在這方面'if'和'while'之間沒有根本的區別。在這兩種情況下,'doSomething(...)'在'isEmpty()'檢查之後,並依靠'synchronized'來防止兩者之間的變化。 – Holger
你說得對,我只是想強調另一個可能的想法。而這是根據給定鏈接中的文檔。 –
你可以顯示你想要比較的代碼嗎? – Joni
這些概念並不矛盾。事實上,你應該總是先檢查條件,然後再等待,否則,如果條件已經滿足,你可能會永遠等待。另一方面,如果條件未滿足,則不可能通過循環成功輪詢,因爲這將表明另一個線程在更改條件時未正確使用「synchronized」。關鍵在於,'wait'暫時釋放監視器,允許另一個線程輸入'synchronized'代碼來改變你正在等待的狀態。 – Holger