используя объект как мьютекс в Java - PullRequest
8 голосов
/ 19 мая 2011

Здравствуйте, добрый человек, мне нужна помощь.

Я пишу музыкальный проигрыватель, который транслирует музыку из Интернета. Если я нажму кнопку воспроизведения до того, как буферизация музыки закончится, я хочу подождать.

Я пытался сделать что-то вроде этого:

Object mutex = new Object();

public void main() {
    startStreaming();
    mutex.notify();
}

private void onClickPlayButton() {
    mutex.wait();
}

Проблема в том, что кнопка воспроизведения не нажимается на mutex.notify(), если выбрасывает "llegalMonitorStateException". Как вы обычно решаете подобные проблемы?

РЕДАКТИРОВАТЬ Чтобы было ясно. У меня вопрос: как заставить кнопку ждать завершения метода startStreamning?

Ответы [ 7 ]

11 голосов
/ 19 мая 2011

Согласно JavaDoc,

IllegalMonitorStateException выбрасывается «чтобы указать, что поток имеет пытался ждать на объекте контролировать или уведомлять другие темы ожидание на мониторе объекта без владеющий указанным монитором. "

Чтобы вызвать mutex.wait() или mutex.notify(), вызывающий поток должен иметь блокировку на объектном мьютексе.

Это исключение выдается, если вы вызываете его без предшествующего synchronized (mutex) { }

Посмотрите красивую анимацию wait и notify по этой ссылке: Как на самом деле работают ожидание и уведомление?

5 голосов
/ 19 мая 2011

для вызовов wait (), notify (), вам нужен синхронизированный код.попробуйте это:

synchronized (this) {
  try {
    this.wait();
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
}


synchronized (this) {
   notify();
}
4 голосов
/ 19 мая 2011

Попробуйте использовать Семафор с 0 начальным разрешением.Семафор мьютекс = новый семафор (0);

в основном mutex.release();

в клик mutex.acquire();

2 голосов
/ 19 мая 2011

из javadoc wait Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта , а для notify Этот метод долженвызываться только потоком, который является владельцем монитора этого объекта.

это означает, что вам нужно синхронизироваться с использованием мьютекса при использовании уведомлений и ожидания

0 голосов
/ 19 мая 2011

Вы можете посмотреть на использование более сложных объектов блокировки или просто создать исключение в блоке try / catch.Последнее определенно «быстрое и грязное».

Для более продвинутой блокировки объектов, посмотрите на http://download.oracle.com/javase/tutorial/essential/concurrency/newlocks.html

0 голосов
/ 19 мая 2011

Вы должны синхронизироваться по мьютексу, чтобы вызвать уведомление и ждать

0 голосов
/ 19 мая 2011

Вы должны wait перед вами notify.

...