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();
}
Другие вопросы по тегам