简单的java同步问题

时间:2010-06-12 03:34:16

标签: java synchronized

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

为什么?

3 个答案:

答案 0 :(得分:4)

我认为两者都很危险,因为您的valuenotmodified检查是在没有同步的情况下执行的。因此,如果methodOne修改了值methodTwo正在验证其是否已更改,则无法确定会发生什么。

我认为你的两个“选择”没有区别。两者都有这个潜在的问题。

答案 1 :(得分: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()
       }
   }
}

答案 2 :(得分:0)

这样的问题可以通过1998年首次发布的并发库得到更好的处理,它在2004年成为JDK 5的一部分。我建议你学习如何使用它们,因为它们通常比notify /更容易使用和理解notifyAll / wait构造。

在您的情况下,您可以使用Condition在其javadoc中发表评论

  

条件因素超出对象   监控方法(等待,通知和   notifyAll)到不同的对象   给出多重的效果   每个对象的等待集合,通过组合   他们使用任意锁   实现。锁取代的地方   使用同步方法和   语句,条件取代了   使用Object监视器方法。

相关问题