[英]Simple java synchronization question
用Groovy代碼簡單一些:#!/ usr / bin / env groovy
public class test {
boolean val
def obj=new Object()
def dos() {
val=false
Thread.start() {
synchronized(obj) {
val=true
obj.notifyAll()
}
}
Thread.sleep(5000)
synchronized(obj) {
while (!val) {
obj.wait()
}
}
}
static void main(String[] args) {
def t=new test()
t.dos()
}
}
好的,這是我的問題的詳細信息。
線程(A)在一個單獨的線程中啟動一個動作,然后等待其完成-可以,這可能不是真的,否則可以使用thread.join()。 該線程實際上啟動了一個任務,然后最終向methodOne發出信號
線程(B)完成動作后收到信號
class A {
private boolean finished
public synchronized void methodOne() {
finished=true;
notifyAll();
}
public void methodTwo() {
new ThreadThatCallsMethodOneWhenDone().start();
synchronized(this) {
while (!finished) {
wait();
}
}
}
}
這段代碼可以嗎,還是我仍然遇到潛在的問題? 有什么更好的解決方法?
米莎
我想知道,這是正確的:
選項一
class A {
public void methodOne() {
synchronized(this) {
modifyvalue
notifyAll()
}
}
public void methodTwo() {
while (valuenotmodified) {
synchronized(this) {
wait()
}
}
}
選項二
class A {
public void methodOne() {
modifyvalue
synchronized(this) {
notifyAll()
}
}
public void methodTwo() {
while (valuenotmodified) {
synchronized(this) {
wait()
}
}
}
為什么呢?
我認為兩者都是危險的,因為您的valuenotmodified
檢查是在沒有同步的情況下執行的。 那么,有沒有說服力,如果發生了什么methodOne
修改的價值,同時methodTwo
是驗證它是否已經改變的過程。
而且我認為您的兩個“選項”沒有區別。 兩者都有這個潛在的問題。
所有對“值”的訪問應同步:
class A {
public void methodOne() {
synchronized(this) {
modifyvalue
notifyAll()
}
}
public void methodTwo() {
synchronized(this) {
if (valuenotmodified) {
wait()
}
}
}
}
請注意,這等效於:
class A {
public synchronized void methodOne() {
modifyvalue
notifyAll()
}
public synchronized void methodTwo() {
if (valuenotmodified) {
wait()
}
}
}
此類問題可以通過並發庫更好地處理,該並發庫於1998年首次發布,並於2004年成為JDK 5的一部分。我建議您學習如何使用它們,因為它們通常比notify / notifyAll / wait更易於使用和理解。結構體。
在您的情況下,您可以在其javadoc中使用Condition注釋
條件將對象監視方法(wait,notify和notifyAll)分解為不同的對象,從而通過與任意Lock實現結合使用,從而使每個對象具有多個等待集。 如果Lock替換了同步方法和語句的使用,而Condition替換了Object監視器方法的使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.