简单的java同步问题

发布于 09-05 13:07 字数 1672 浏览 4 评论 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 最终发出信号

Thread (B) 当操作完成时,我们会收到一个信号

class A {
   private boolean finished

   public synchronized void methodOne() {
       finished=true;
       notifyAll();
   } 

   public void methodTwo() {
       new ThreadThatCallsMethodOneWhenDone().start();
       synchronized(this) {
           while (!finished) {
                 wait();
           }
       }
   }
}

这段代码可以吗?还是我仍然遇到潜在的问题?有什么更好的办法解决吗?

Misha


我想知道哪个是正确的:

选项一

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

,为什么?

In Groovy code something simple:
#!/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()
  }
}

Ok, here is my problem in more detail.

Thread (A)
start an action in a separate thread, then wait for its completion
-- OK THIS IS NOT EXACTLY TRUE OTHERWISE COULD USE thread.join(). This
Thread actually starts a task that then signals methodOne eventually

Thread (B)
we get a signal when action is completed

class A {
   private boolean finished

   public synchronized void methodOne() {
       finished=true;
       notifyAll();
   } 

   public void methodTwo() {
       new ThreadThatCallsMethodOneWhenDone().start();
       synchronized(this) {
           while (!finished) {
                 wait();
           }
       }
   }
}

Is this code okay or am I still running into potential problems? What's a better way to solve?

Misha


I was wondering, which is correct:

Option One

class A {
   public void methodOne() {
       synchronized(this) {
           modifyvalue
           notifyAll()
       }
   }

   public void methodTwo() {
       while (valuenotmodified) {
           synchronized(this) {
              wait()
           }
       }
   }

Option Two

class A {
   public void methodOne() {
       modifyvalue
       synchronized(this) {
           notifyAll()
       }
   }

   public void methodTwo() {
       while (valuenotmodified) {
           synchronized(this) {
              wait()
           }
       }
   }

and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只涨不跌2024-09-12 13:07:41

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

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

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.

笔芯2024-09-12 13:07:41

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

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

All access to "value" should be synchronized:

class A {
   public void methodOne() {
       synchronized(this) {
           modifyvalue
           notifyAll()
       }
   }

   public void methodTwo() {
       synchronized(this) {
           if (valuenotmodified) {
              wait()
           }
       }
   }

}

Note that this is equivalent to:

class A {
   public synchronized void methodOne() {
       modifyvalue
       notifyAll()
   }

   public synchronized void methodTwo() {
       if (valuenotmodified) {
          wait()
       }
   }
}
停顿的约定2024-09-12 13:07:41

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

在您的情况下,您可以使用 Condition< /a> 在其 javadoc 中注释

条件因素排除对象
监视方法(等待、通知和
notificationAll) 到不同的对象中
达到拥有多个的效果
每个对象的等待集,通过组合
他们与任意Lock的使用
实施。锁取代的地方
使用同步方法和
语句,条件替换
使用对象监视器方法。

Problems like this are better handled by the concurrency library, first released in 1998, it became part of JDK 5 in 2004. I suggest you learn how to use these as they are usually much easier to use and understand than the notify/notifyAll/wait constructs.

In your case you could use Condition In its javadoc it comments

Condition factors out the Object
monitor methods (wait, notify and
notifyAll) into distinct objects to
give the effect of having multiple
wait-sets per object, by combining
them with the use of arbitrary Lock
implementations. Where a Lock replaces
the use of synchronized methods and
statements, a Condition replaces the
use of the Object monitor methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文