Java等待特定间隔通知不工作

Java等待特定间隔通知不工作,java,wait,intervals,notify,Java,Wait,Intervals,Notify,代码段: class Counter implements Runnable { Object s = new Object(); @Override public void run() { try { synchronized (s) { s.wait(10000); } } catch (InterruptedException e) {

代码段:

class Counter implements Runnable {
    Object s = new Object();

    @Override
    public void run() {
        try {
            synchronized (s) {
                s.wait(10000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //...do Something
    }

    public void stopCounter() {
        synchronized (s) {
            s.notifyAll();
        }   
    }
}

不管我是否调用stopCounter,…do Something代码总是在等待间隔之后执行。即使在通知之后,它仍然会等待10秒。

这取决于您使用它的方式。我刚刚添加了一个main方法并运行了它,似乎wait/notify机制运行得很好,而不是您描述的方式。请自己试一试:

public static void main(String[] args) {
  Counter c = new Counter();
  new Thread(c).start();
  try {
    Thread.sleep(1000);
  } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  c.stopCounter();
}

我猜您在
计数器
类的不同实例上调用
run
stopCounter
方法。因此,它们使用不同的监视器(您的
s=new Object()
),对stop的调用不会通知其他计数器

例如,这与您描述的行为类似(除非您得到虚假唤醒):


我无法从你的例子中看出你在努力实现什么。如果要尝试替换某种轮询,那么考虑在java 5中发布的接口。从那以后,我就不需要等待/通知了。它的使用要简单得多,java幕后为您做了相当于等待/通知的工作。

在调用
stopCounter()
之前是否更改变量
s
?由于虚假唤醒,对wait的调用几乎总是处于循环中。基本上,当为同一对象调用notify或notifyAll时,wait将始终返回。但它也可能因为任何原因或根本没有任何原因而返回。所以你需要某种信号(通常是一个易变的布尔变量)和一个循环。每次wait返回时,请检查变量,如果变量未达到所需值,请再次等待。如果您的目标是通常等待10秒,但有时会提前醒来,则最好使用Thread.sleep(没有虚假唤醒)和Thread.interrupt(当您希望休眠线程醒来时)不,我使用的是计数器的同一个实例。不,我使用的是同一个实例,我还执行了上面的代码。“通知”会立即打印,但“输出”会在10秒后打印。我建议您显示所有相关代码,以便我们重现您观察到的行为。我执行了您粘贴的代码,我希望在“通知”打印后“输出”会打印出来。但10秒后就会打印出来。是否立即为您打印?否,
out
在我的机器上打印10秒后,这是我的代码的预期行为。@Rakesh抱歉,现在没有时间聊天。但可能发生的情况是,在调用wait之前调用notify(不一定是按照程序顺序,但这是机器在各个线程中命令指令的方式)——因此,一旦调用wait,因为notify事件已经消失,它将等待到超时。
public static void main(String[] args) throws InterruptedException {
    Counter c = new Counter();
    new Thread(c).start();
    Thread.sleep(200);
    new Counter().stopCounter();
}

static class Counter implements Runnable {

    Object s = new Object();

    @Override
    public void run() {
        try {
            System.out.println("in");
            synchronized (s) {
                s.wait(10000);
            }
            System.out.println("out");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //...do Something
    }

    public void stopCounter() {
        synchronized (s) {
            s.notifyAll();
        }
        System.out.println("notified");
    }
}