Простой вопрос параллелизма Java - PullRequest
2 голосов
/ 28 ноября 2010

Тема 1:

if(!conditionFullfiled) this.wait();

Тема 2:

if(conditionFullfiled) thread1.notify();

Я хочу разбудить поток 1 из потока 2, когда какое-либо условие выполнено. Но разве нет проблемы, когда thread1.notify() называется if(!conditionFullfiled) ***HERE*** this.wait();?

Ответы [ 4 ]

3 голосов
/ 28 ноября 2010

У вас 2 проблемы здесь.

  1. вы не должны вызывать wait () и notify () для самого объекта потока. Лучший способ сделать это - использовать специальный объект блокировки, например,

    закрытый объект блокировки = новый объект (); ...... lock.wait ();

  2. Следующая проблема заключается в том, что вы должны вызывать и wait (), и уведомлять синхронизированный блок, т.е.

    синхронизирован (блокировка) { // некоторый код lock.wait (); }

тогда в другом месте в коде говорят:

syncronized(lock) {
    lock.notify(); // this line will cause the wait to terminate and the first thread to continue.
}

Удобно локализовать методы обёртывания wait() и notify() в одном классе, чтобы они имели доступ к объекту блокировки.

Для получения дополнительной информации читайте http://download.oracle.com/javase/6/docs/api/ http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html

3 голосов
/ 28 ноября 2010

Чтобы сделать obj.wait() и obj.notify(), вам необходимо иметь монитор объекта, о котором вы собираетесь ожидать / уведомить.В вашем коде вы, вероятно, не хотите thread1.notify ().Пример:

   Object someSharedObject = ...

Тема 1:

   synchronized(someSharedObject) {
     // while NOT if for spurious wake ups.
     while(!conditionFullfiled) someSharedObject.wait();
   }

Тема 2:

   synchronized(someSharedObject) {
     if(conditionFullfiled) someSharedObject.notify(); // this wakes thread1
   }

Блокировка synchronized включена someSharedObject (может быть this)Это означает, что два потока никогда не будут конфликтовать..wait() освобождает текущий удерживаемый монитор, поэтому Thread2 не будет блокироваться, когда Thread1 ожидает.

Редактировать: Я кое-что узнал о ложных пробуждениях..wait() должно быть выполнено в цикле while - if недостаточно. Почему потоки самопроизвольно просыпаются от wait ()? .Спасибо Энно Сиоджи за то, что научил меня.

Редактировать: Уточнено .wait() выпускает монитор.

0 голосов
/ 28 ноября 2010

Никаких проблем, так как ожидание снимает блокировку объекта (в этом случае).

Рекомендуется охранять условия ожидания / уведомления в блоках while - чтобы избежать ложных пробуждений.

0 голосов
/ 28 ноября 2010

Какой объект вы используете как «это»?Если вы вызываете wait () для объекта thread1, и оба показанных вами оператора будут заключены в цикл, подобный следующему:

new Runnable() {
    synchronized (thread1) {
        thread1.wait() 
    }
}

Тогда ваш код будет работать так, как вы хотите.(Первый поток будет остановлен, когда условие ложно, и будет работать иначе).Хитрость заключается в том, что взаимодействия с объектом потока синхронизируются, поэтому один поток не может прерывать, пока другой работает с объектом.

РЕДАКТИРОВАТЬ: будет еще лучше, если вы синхронизируете не в потоке, а вкакой-то другой объект (вы можете просто создать чистый объект для обеспечения блокировки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...