Кто-нибудь может объяснить нить мониторов и ждать?

Как только вы открыли CLI mongo, подключили и авторизировали в правой базе данных.

В следующем примере показано, как найти документ с помощью _id = 568c28fffc4be30d44d0398e из коллекция под названием «продукты»:

blockquote>
db.products.find({"_id": ObjectId("568c28fffc4be30d44d0398e")})

38
задан Bill K 22 October 2008 в 22:31
поделиться

6 ответов

Если объект не будет владеть объектным монитором, когда это назовет Object.wait (), это не будет в состоянии получить доступ к объекту установить уведомлять слушателя до, монитор выпущен. Вместо этого это будут рассматривать как поток, пытающийся получить доступ к методу на синхронизируемом объекте.

Или, другими словами, нет никакого различия между:

public void doStuffOnThisObject()

и следующий метод:

public void wait()

Оба метода будут заблокированы, пока объектный монитор не будет выпущен. Это - функция в Java для препятствования состоянию объекта быть обновленным больше чем одним потоком. Это просто имеет непреднамеренные последствия на ожидании () метод.

, По-видимому, ожидание () метод не синхронизируется, потому что это могло создать ситуации, где Поток имеет, несколько соединяют объект. (См. Спецификации/Блокировка Языка Java для большего количества информации об этом.) Несколько блокировок являются проблемой, потому что ожидание () метод только отменит одну блокировку. Если бы метод синхронизировался, он гарантировал бы, что только блокировка метода будет отменена, все еще оставляя потенциальную внешнюю блокировку отмененной. Это создало бы условие мертвой блокировки в коде.

Для ответа на вопрос на Thread.sleep () Thread.sleep () не гарантирует, что безотносительно условия, на котором Вы ожидаете, был встречен. Используя Object.wait () и Object.notify () позволяет программисту вручную реализовывать блокирование. Потоки разблокируют, как только уведомление отправляется это, условие соблюдали. например, чтение от диска закончилось, и данные могут быть обработаны потоком. Thread.sleep () потребовал бы, чтобы программист опросил, если условие соблюдали, то отступает ко сну, если это не имеет.

4
ответ дан 64BitBob 22 October 2008 в 22:31
поделиться
  • 1
    Спасибо, неутешительное но информативное. – Bill Forster 29 June 2011 в 09:51

Много хороших ответов здесь уже. Но просто хочу упомянуть здесь, что другой ДОЛЖЕН СДЕЛАТЬ, когда использование ожидает (), должен сделать это в цикле, зависящем от условия, Вы ожидаете того, в случае, если Вы видите побочные пробуждения, которые, по моему опыту, происходят.

Для ожидания некоторого другого потока, чтобы изменить условие на истинный и уведомить:

synchronized(o) {
  while(! checkCondition()) {
    o.wait();
  }
}

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

 Lock lock = new ReentrantLock();
 Condition condition = lock.newCondition();
 lock.lock();
 try {
   while (! checkCondition()) {
     condition.await();
   }
 } finally {
   lock.unlock();
 }

}

14
ответ дан Alex Miller 22 October 2008 в 22:31
поделиться
  • 1
    Я пытаюсь найти точную кавычку, которая объясняет , где вектор, который инстанцируют в вышеупомянутом коде. Какие-либо подсказки? – David Rodríguez - dribeas 29 June 2011 в 08:00

Ожидайте бросает монитор, таким образом, у Вас должен быть он для отказа от него. Уведомьте должен иметь монитор также.

главная причина, почему Вы хотите сделать, это должно гарантировать, чтобы у Вас был монитор, когда Вы возвращаетесь из ожидания () - обычно, Вы используете ожидать/уведомлять протокол для защиты некоторого совместно используемого ресурса, и Вы хотите, чтобы он был безопасен коснуться его, когда ожидают возвраты. То же с уведомляет - обычно, что Вы изменяете что-то и затем звоните, уведомляют () - что Вы хотите иметь монитор, внести изменения, и вызов уведомляет ().

, Если Вы сделали функцию как это:

public void synchWait() {
   syncronized { wait(); }
}

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

5
ответ дан Lou Franco 22 October 2008 в 22:31
поделиться
  • 1
    Код как есть (т.е. тип, который содержит вектор it' s собственный тип), является неправильным, независимо от того, предоставляете ли Вы конструкторам, операторам присваивания или ни одному из них.. – David Rodríguez - dribeas 29 June 2011 в 15:41

Вот мое понимание того, почему ограничение является на самом деле требованием. Я основываю это на реализации монитора C++, которую я сделал некоторое время назад путем объединения взаимного исключения и условной переменной.

В система mutex+condition_variable=monitor , эти ожидают , вызов устанавливает условную переменную в состояние ожидания и выпускает взаимное исключение. Условная переменная является общим состоянием, таким образом, это должно быть заблокировано для предотвращения условий состязания между потоками, которые хотят ожидать и потоки, которые хотят уведомить. Вместо того, чтобы представить еще одно взаимное исключение для блокировки его состояния используется существующее взаимное исключение. В Java правильно заблокировано взаимное исключение, когда поток about-to-wait владеет монитором.

3
ответ дан Mr Fooz 22 October 2008 в 22:31
поделиться
  • 1
    +1: Намного более хороший, чем мое решение. I' ll украсть этот код. – Blender 3 February 2012 в 20:38

Это должно владеть монитором, так как цель ожидания () состоит в том, чтобы выпустить монитор и позволить другим потокам получить монитор, чтобы сделать собственную обработку. Цель этих методов (ожидает/уведомляет), должен скоординировать доступ к синхронизируемым блокам кода между двумя потоками, которые требуют друг друга для выполнения некоторой функциональности. Это не просто вопрос доступа проверки к структуре данных, ориентировано на многопотоковое исполнение, но скоординировать события между несколькими потоками.

классическим примером А был бы случай производителя/потребителя, где один поток продвигает данные очереди, и другой поток использует данные. Поток потребления всегда требовал бы, чтобы монитор получил доступ к очереди, но выпустит монитор, как только очередь пуста. Поток производителя тогда только заставил бы доступ писать в поток, когда потребитель больше не обрабатывает. Это уведомило бы потребительский поток, как только это продвинуло больше данных в очередь, таким образом, это может возвратить монитор и получить доступ к очереди снова.

5
ответ дан Robin 22 October 2008 в 22:31
поделиться
  • 1
    @Benjamin, благодарит занять время для комментария. Я принимаю точку об этом не имеющий никакого отношения к его вопросу о неполном тип. вектору нужен конструктор копии; в его случае, по умолчанию. он спросил, было ли что-нибудь для внимательности, я думал, что на это стоило указать. – Blazes 29 June 2011 в 09:10

В основном ожидание выполняется, если есть условие, что очередь пуста.

If(queue is empty)
     queue.wait();

Предположим, очередь пуста. В случае, если текущий поток прерывается после проверки очереди, то если другой поток добавляет несколько элементов в очередь, текущий поток не будет знать и будет ждать государство. Это неверно. Итак, у нас должно получиться что-то вроде

Synchornized(queue)
{
   if(queue is empty)
          queue.wait();
}

. Теперь давайте рассмотрим, что, если бы они заставили себя ждать как синхронизированные. Как уже упоминалось в одном из комментариев, он снимает только одну блокировку. Это означает, что если бы wait () был синхронизирован в приведенном выше коде, была бы снята только одна блокировка. Подразумевается, что текущий поток будет ждать с блокировкой очереди.

3
ответ дан 27 November 2019 в 01:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: