Какая лучшая альтернатива ждать... уведомлять о синхронизации низкого уровня?
Насколько я знаю, wait()
и notify()
были заменены на лучшие механизмы concurrency. Итак, какую лучшую альтернативу вы бы выбрали, скажем, для реализации синхронизированной очереди?
В каком смысле они "лучше"?
Изменить. Это ( "реализовать синхронную очередь" ) является вопросом интервью. Допустимый ответ не может использовать BlockingQueue или другую реализацию очереди. Однако он может использовать другие конструкции синхронизации, такие как CountDownLatch. У меня нет исчерпывающего списка разрешенных и запрещенных классов - используйте свои головы.
Ответы
Ответ 1
synchronized/wait()/notify()/notifyAll()
были напрямую заменены методами класса Lock lock()/unlock()/newCondition()
и Condition await()/signal()/signalAll()
.
Есть несколько преимуществ для них, для начала допускающих дополнительную семантику, таких как политики справедливости, а также такие функции, как распределенная блокировка. Поддержка нескольких объектов Condition
допускает гораздо более мелкозернистую сигнализацию, а также бесперебойное ожидание и ожидание до некоторого времени и т.д.
Например, связанный код имеет отдельные объекты, которые он пытается использовать для сигнализации (что не удастся из-за того, что соответствующие мониторы не удерживаются при ожидании). Это можно сменить с помощью одного замка с несколькими условиями.
С точки зрения усовершенствований, дополнительная функциональность может быть полезной. В Java5 явные реализации блокировки фактически выполняются лучше, чем мониторы JVM, но они в основном порезали код Doug Lea для JVM, и производительность теперь примерно эквивалентна.
Ответ 2
В пакете java.util.concurrent
уже реализовано множество реализаций. Например. - ArrayBlockingQueue
, DelayQueue
, LinkedBlockingQueue
, PriorityBlockingQueue
, SynchronousQueue
.
Также wait()
и notify()
не были заменены. Были введены новые утилиты, которые обеспечивают дополнительные функциональные возможности и преимущества производительности. См. Например пакет java.util.concurrent.locks
.
Я бы рекомендовал вам прочитать это введение. Он дает высокий обзор, который должен отвечать на ваш вопрос.
Приветствия.
Изменить 1: Хорошо, тогда, например, вы можете использовать реализацию java.util.concurrent.locks
.Lock
для реализации операции детекции, в которой тайм-аут и в то же время обеспечивает справедливость для потоков, обращающихся к очереди. Такая реализация ReentrantLock
, которая имеет конструктор, который принимает политику справедливости. Приоритет tryLock()
поддерживает это свойство. Также вы можете добавить некоторую поддержку отладки для подсчета ожидающих потоков в очереди и т.д. Это было бы намного сложнее реализовать с помощью wait()
и notify()
.
В заключение ReentrantLock
"лучше", чем аналогичные элементы низкого уровня в своих расширенных возможностях. Однако основное поведение остается тем же. Если вам не нужны эти дополнительные функции wait()
и notify()
, все еще приемлемая альтернатива.
Ответ 3
Чтение источника ArrayBlockingQueue показывает использование Условия в качестве замены методов мониторинга объекта "wait/notify/notifyAll". Кроме того, вместо "синхронизированного" ключевого слова используется ReentrantLock, чтобы достичь аналогичного поведения и семантики взаимного исключения. Итак, кажется, что java.util.concurrent.locks - это то, что вы ищете. Эти новые интерфейсы лучше, потому что они обеспечивают дополнительную функциональность, недоступную исходным конструкциям синхронизации и блокировки, таким как несколько наборов ожидания и выборочные блокировки чтения или записи (а не всегда как чтение, так и запись).
Пакет java.util.concurrent.atomic также предоставляет интерфейсы для compare-and-swap, которые полезны для неблокирующих алгоритмов, которые потенциально намного быстрее, чем их блокирующие альтернативы, но имеют свои собственные проблемы.
Ответ 4
park() методы unpark() класса LockSupport кажутся полезными в этом случае.
Я также столкнулся с такими же вопросами и при поиске в сети нашел в этой дискуссии ключ.
Синхронизация и блокировка
Но мне нужно понять концепции далее, чтобы создать пример приложения.
Ответ 5
Как использовать семафор из параллельного пакета?
Использование двоичного семафора в качестве встроенной блокировки и двух подсчетов семафоров для установки привязки по размеру очереди?