[英]Wake waiting threads in java
我有4个线程正在同时填充50000000x4矩阵。 为了确保写入的安全性,我使用AtomicInteger作为指针。 每次迭代时,每个线程都会将指针值复制到threadPointer中,并使用它来填充。 获取指针== buffer.length的第一个线程启动例程,将缓冲区刷新到内存中。 此时,其他线程应等待线程完成其工作。 这是我的代码:
if ((threadPointer = pointer.getAndAdd(1)) >= buffer.length ){
synchronized (flag){
if(threadPointer == buffer.length){
sampledSelection();
pointer.set(0);
threadPointer = pointer.getAndAdd(1);
flag.notifyAll();
}else{
System.out.println("waiting");
flag.wait();
threadPointer = pointer.getAndAdd(1);
System.out.println("Awaken!");
}
}
}
我的问题是notifyAll()
不会唤醒正在等待的线程。我该如何解决?
听起来你想通了,但后代...
我的问题是notifyAll不会唤醒等待的线程。 我怎样才能解决这个问题?
是的,您在这里拥有经典的比赛条件。 假设有3个线程大约在同一时间执行pointer.getAndAdd(1)
。
synchronized (flag)
并进入保护区域。 synchronized (flag)
但是它们被锁定,直到线程#1解锁。 pointer
值等于缓冲区长度,因此它调用sampledSelection();
,将pointer
重置为0,调用notifyAll()
,然后解锁。 synchronized
部分。 它的pointer
值不相等,所以它进入了解锁的wait()
。 synchronized
部分。 它的pointer
值不相等,所以它进入了解锁的wait()
。 如果没有人再次调用notifyAll()
那么他们将永远等待。
如您所知,重要的是要认识到notifyAll()
方法唯一起作用的时间就是线程是否已经在等待 。 通常应该发生的是线程应查看条件字段以查看是否应等待。
要注意的另一件事是确保synchronized
的对象是常量。 在您的情况下, flag
应定义为:
private final Object flag = new Object();
如果可以将您的flag
分配给另一个值,则线程将不会锁定(或发出信号)在同一对象上,这将导致问题。 始终确保锁定final
对象。
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.