Java ждать определенный интервал уведомления не работает
Фрагмент кода:
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 секунд.
3 ответа
Я не могу сказать из вашего примера, чего вы пытаетесь достичь. Если это попытка заменить какой-либо опрос, рассмотрите интерфейс BlockingQueue, который был выпущен в Java 5. С тех пор, как он появился, у меня не было необходимости ждать / уведомлять. Это намного проще в использовании, а Java за кулисами делает эквивалент ожидания / уведомления для вас.
Я думаю, что вы называете run
а также stopCounter
методы в разных случаях вашего Counter
учебный класс. Поэтому они используют разные мониторы (ваш s = new Object()
) и вызов Stop не уведомит другой счетчик.
Например, это будет вести себя аналогично тому, что вы описываете (если вы не получили ложного пробуждения):
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");
}
}
Это зависит от того, как вы его используете. Я только что попробовал, добавив основной метод и запустив его, и кажется, что механизм ожидания / уведомления работает нормально, а не так, как вы описали это. Пожалуйста, попробуйте сами:
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();
}