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");
}
}