繁体   English   中英

在Java中唤醒等待线程

[英]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)

  1. 线程1首先调用synchronized (flag)并进入保护区域。
  2. 线程#2和#3调用synchronized (flag)但是它们被锁定,直到线程#1解锁。
  3. 线程#1的pointer值等于缓冲区长度,因此它调用sampledSelection(); ,将pointer重置为0,调用notifyAll() ,然后解锁。
  4. 现在,线程2(让我们说)进入synchronized部分。 它的pointer值不相等,所以它进入了解锁的wait()
  5. 线程#3现在进入synchronized部分。 它的pointer值不相等,所以它进入了解锁的wait()

如果没有人再次调用notifyAll()那么他们将永远等待。

如您所知,重要的是要认识到notifyAll()方法唯一起作用的时间就是线程是否已经在等待 通常应该发生的是线程应查看条件字段以查看是否应等待。

要注意的另一件事是确保synchronized的对象是常量。 在您的情况下, flag应定义为:

private final Object flag = new Object();

如果可以将您的flag分配给另一个值,则线程将不会锁定(或发出信号)在同一对象上,这将导致问题。 始终确保锁定final对象。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM