0

在 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()
           }
       }
   }

为什么?

4

3 回答 3

4

I think that both are dangerous because your valuenotmodified check is performed without synchronisation. So, there is no telling what happens if methodOne modifies the value while methodTwo is in process of verifying whether it has changed.

And I see no difference between your two "options". Both have this potential problem.

于 2010-06-12T03:44:41.567 回答
0

所有对“价值”的访问都应该同步:

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()
       }
   }
}
于 2010-06-12T09:28:06.020 回答
0

并发库可以更好地处理此类问题,该库于 1998 年首次发布,2004 年成为 JDK 5 的一部分。我建议您学习如何使用它们,因为它们通常比 notify/notifyAll/wait 更容易使用和理解结构体。

在您的情况下,您可以 在其 javadoc 中使用Condition它注释

Condition 将对象监视器方法(wait、notify 和 notifyAll)分解为不同的对象,通过将它们与任意 Lock 实现的使用结合起来,使每个对象具有多个等待集的效果。Lock 代替了同步方法和语句的使用,Condition 代替了 Object 监视器方法的使用。

于 2010-06-12T10:00:51.450 回答