簡體   English   中英

簡單的Java同步問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM