Как wait() возвращает Lock в Java
Это парадигма, которая выступает в качестве ожидания при вызове wait() внутри цикла while внутри синхронизированного блока.
Мой вопрос в том, как поток ожидания() возвращает блокировку?
// Thread 1
synchronized (mon) {
while (!condition)
mon.wait();
// Do something
}
//Thread 2
synchronized (mon) {//set condition appropriately
mon.notify();
}
Рассмотрим, что поток 1 запускается первым и начинает ждать условия. Он освобождает блокировку, и поток 2 получает блокировку, устанавливает условие и уведомляет поток 1. Теперь поток 1 получает блокировку, проверяет состояние и начинает выполнение "сделать что-то".
Мой вопрос в том, что когда Thread 1 уведомляется о том, что он запускает выполнение из условия while, строка кода, которая была синхронизирована (mon), никогда не выполняется снова, а затем, как поток 1 получает блокировку? Какова внутренняя динамика, которая возвращает блокировку Thread 1?
Ответы
Ответ 1
Когда Thread1 уведомляется, поток должен получить блокировку, прежде чем он сможет выйти из метода wait, см. java doc для Object # wait:
Затем поток T
удаляется из набора ожидания для этого объект и повторно включен для планирования потоков. Затем он конкурирует в обычный способ с другими потоками для права синхронизации на объект; как только он получит контроль над объектом, все его требования синхронизации к объекту восстанавливаются в статус-кво ante - то есть к ситуации со временем, когда wait
метод был вызван. Тема T
затем возвращает из вызов метода wait
. Таким образом, по возвращении из wait
, состояние синхронизации объекта и потока T
точно так же, как и когда метод wait
вызывается.
Ответ 2
synchronized(mon)
не является выражением, которое должно выполняться.
Это синтаксический элемент в исходном коде, который сообщает компилятору (а затем и время выполнения), что завернутая секция кода должна выполняться только после того, как блокировка, связанная с mon
, была получена текущим потоком, даже если вы не "выходите" из строки кода перед синхронизированным блоком.
wait()
освобождает замок и должен вернуть его перед возвратом.
Ответ 3
После того, как Thread 1 будет уведомлен, он немедленно получит блокировку и начнет работать//Сделайте что-нибудь.
Когда Thread 1 ждет, он просто временно отключает блокировку, и когда поток уведомляется, он может снова получить блокировку и не должен запускаться синхронно (...).
Ответ 4
// Thread 1
synchronized (mon) {
Systemout.println("I am invoked!");
while (!condition)
mon.wait();
// Do something
}
//Thread 2
synchronized (mon) {//set condition appropriately
mon.notify();
}
В исходном сценарии:
Рассмотрим, что поток 1 запускается первым и начинает ждать условия. Он освобождает блокировку, и поток 2 получает блокировку, устанавливает условие и уведомляет поток 1. Теперь поток 1 получает блокировку, проверяет состояние и начинает выполнение "сделать что-то".
Если я правильно понимаю следующее:
Затем поток T удаляется из набора ожидания для этого объекта и снова включается для планирования потоков. Затем он конкурирует обычным образом с другими потоками для права на синхронизацию с объектом; как только он получит контроль над объектом, все его требования к синхронизации объекта возвращаются в статус-кво ante, то есть к ситуации с момента вызова метода wait. Затем поток T возвращается из вызова метода wait. Таким образом, при возврате из метода wait состояние синхронизации объекта и потока T происходит точно так же, как и при вызове метода wait.
линия Systemout.println( "Я вызван!" );
не будет выполняться, так как "Таким образом, при возврате из метода ожидания состояние синхронизации объекта и потока T точно такое же, как и при вызове метода wait".
Я прав?