В настоящее время я изучаю параллельное программирование на Java. Я замечаю, что LockSupport.park()
введенный в Java 1.6, намного проще, чем Object.wait()
для использования, типичное использование Object.wait()
похоже
// Thread1
synchronized (lock) {
while (condition != true) {
lock.wait()
}
// do stuff
}
// Thread2
synchronized (lock) {
condition = true;
lock.notify();
}
И я думаю, что могу переписать его с помощью LockSupport.park()
как
// Thread1
while (condition != true) {
LockSupport.park();
}
// do stuff
// Thread2
condition = true;
LockSupport.unpark(Thread1);
Используя LockSupport.park()
, утомительный synchroinzed
блок исчезает.
Мой вопрос: должен ли я всегда предпочитать LockSupport.park()
чем Object.wait()
? Есть ли какой-либо аспект, который Object.wait()
делает лучше, чем LockSupport.park()
например, производительность?
Идея ожидания/уведомления заключается в том, что уведомления не зависят от потоков, но уведомитель не должен знать конкретный поток, который должен уведомлять, он просто сообщает блокировке (или условию для ReentrantLock), которую он уведомляет, и блокировка и планировщик ОС между ними определяют, кто получает уведомление.
Я бы ожидал, что большую часть времени уведомитель не захочет знать, какой поток нужен для переадресации, поэтому wait/notify будет лучшим выбором для этих случаев. С парком /unpark ваш код должен знать больше, и будет больше возможностей для отказа. Вы можете подумать, что синхронизированный блок утомительный, но то, что действительно утомительно, - это сортировка случаев, когда что-то не становится неактивным, когда оно должно быть.
Обратите внимание, что в вашем втором примере ваше состояние должно быть изменчивым или Atomic или иначе, где его обновления видны в потоках.
wait()
- это Condition
, а для synchroinzed
это Lock
. Condition
должно быть получено из Lock
также отражает отношения wait()
и synchronized
. LockSupport.park()
является их основой.