在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()
}
}
}
为什么?
答案 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监视器方法。