Может ли `LockSupport.park ()` заменить `Object.wait ()`?

2

В настоящее время я изучаю параллельное программирование на 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() например, производительность?

  • 0
    Я не уверен, но одна вещь, которая приходит на ум, состоит в том, что из документов не ясно, обеспечивают ли методы LockSupport какую-либо видимость памяти, гарантирующую, что синхронизация обеспечивает (происходит до краев и все такое).
  • 0
    См. Также вопрос Практические примеры LockSupport / AbstractQueuedSynchronizer .
Теги:
multithreading
wait
locking

1 ответ

4
Лучший ответ

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

Я бы ожидал, что большую часть времени уведомитель не захочет знать, какой поток нужен для переадресации, поэтому wait/notify будет лучшим выбором для этих случаев. С парком /unpark ваш код должен знать больше, и будет больше возможностей для отказа. Вы можете подумать, что синхронизированный блок утомительный, но то, что действительно утомительно, - это сортировка случаев, когда что-то не становится неактивным, когда оно должно быть.

Обратите внимание, что в вашем втором примере ваше состояние должно быть изменчивым или Atomic или иначе, где его обновления видны в потоках.

  • 0
    Изучив javadoc связанных классов, я понял, что замена для wait() - это Condition , а для synchroinzed это Lock . Condition должно быть получено из Lock также отражает отношения wait() и synchronized . LockSupport.park() является их основой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню