Убедитесь, что синхронизированные блокировки Java выполняются в порядке?
-
05-07-2019 - |
Вопрос
у нас есть два потока, обращающихся к одному списку через синхронизированный метод.Можем мы
а) полагаться на время выполнения, чтобы убедиться, что каждый из них получит доступ к методу в зависимости от порядка, который они пытались выполнить, или
б) соблюдает ли виртуальная машина какие-либо другие правила
в) есть ли лучший способ сериализации запросов?
Решение
Нет, синхронизированный предоставит доступ в любом порядке (зависит от реализации JVM). Это может даже привести к тому, что потоки начнут голодать в некоторых сценариях. Р>
Вы можете обеспечить порядок, используя ReentrantLock (начиная с Java 5.0) с параметром fair = true
. ( Lock lock = new ReentrantLock (true);
)
Другие советы
Нет, вы не можете быть уверены, что два вызова синхронизированного метода будут происходить по порядку. Порядок не указан и зависит от реализации.
Это определено в 17.1 блокировок Раздел JLS. Обратите внимание, что это ничего не говорит о порядке, в котором потоки, ожидающие блокировки, должны получить доступ.
Нельзя полагаться на порядок, в котором конкретный метод вызывается из каждого потока. Если это только две темы, может быть да. Но представьте, если 3 потока и 1 поток уже получили доступ. Другие 2 потока при попытке доступа будут ожидать, и любой из них может получить доступ, и это не зависит от порядка, в котором они вызвали этот метод. Поэтому не рекомендуется полагаться на порядок.
в) есть ли лучший способ сериализации запросов?
Вы случайно не используете список в качестве очереди, то есть шаблон использования выглядит примерно так?
while (some condition) { synchronized(theList){ anItem = get and remove an element from theList } do some work with anItem }
Если это так, вы можете посмотреть на BlockingQueue
вместо использования собственных схем блокировки. Реализации (например, ArrayBlockingQueue код>
) имеет настройки для справедливости и многое другое.
Я всегда оставляю синхронизацию серверу приложений или движку, если не определяю собственную интенсивность
Да.
Если доступ к списку осуществляется через один синхронизированный метод, одновременные запросы от нескольких потоков будут сериализованы.