Разница между синхронизацией и блокировкой повторного входа? - программирование
Подтвердить что ты не робот

Разница между синхронизацией и блокировкой повторного входа?

Я использовал ключевое слово synchronized и блокировки повторного входа в Java, но я не понимаю, как они отличаются или что подходит для данной ситуации.

Как мне решить, когда следует использовать synchronized и когда я должен использовать блокировки повторного входа?

4b9b3361

Ответ 1

A ReentrantLock:

Повторное взаимное исключение Блокировка с тем же основным поведением и семантика, поскольку доступ к неявной блокировке монитора осуществляется с помощью синхронизированного методы и утверждения, но с расширенными возможностями.

Расширенные возможности включают:

  • Возможность иметь более одного параметра переменная условия для каждого монитора. Мониторы, использующие ключевое слово synchronized, могут иметь только один. Это означает, что блокировки реентера поддерживают более одной очереди wait()/notify().
  • Возможность сделать блокировку fair. Синхронизированные блоки несправедливы.

    "[fair] блокирует возможность предоставления доступа к самому длинному ожидающему потоку. В противном случае эта блокировка не гарантирует какого-либо определенного порядка доступа.

  • Возможность проверки блокировки блокировки.
  • Возможность получения списка потоков, ожидающих блокировки.

Недостатками блокировки реентера являются:

  • Необходимо добавить оператор импорта.
  • Нужно обернуть захват блокировки в блок try/finally. Это делает его более уродливым, чем синхронизированное ключевое слово.
  • Ключевое слово synchronized может быть помещено в определения методов, что позволяет избежать необходимости в блоке, который уменьшает вложенность.

Резюме

Ключевое слово synchronized синтаксически лучше, но блокировка реентера имеет больше возможностей.

Ответ 2

Я всегда думал о синхронизации как о "руке наименьшего сопротивления". Это просто работает, и большинство людей понимает, как это работает, но оно имеет некоторые недостатки, которые могут повлиять на ваш дизайн при тяжелых concurrency. Не последним из которых является любой клиент, который имеет непосредственный доступ к блокировке синхронизации объекта, если они хватают его и удерживают его, другие клиенты не могут. Другими словами, блокировка, реализованная по умолчанию, синхронизируется эффективно, "публикует" механизм внутреннего блокирования объекта. ЮК. Это похоже на самоотверженный отказ в обслуживании.

Если вы сделаете блокировку ретентата внутренней для своего класса (или просто не используйте синхронизированный, но выполняйте что-то вроде синхронизации на каком-либо внутреннем объекте, который вы новичок в своем конструкторе повсюду, который вы хотите синхронизировать), вы удаляете эту сторону, эффект публикации механизма внутренней блокировки, с дополнительной сложностью вы должны помнить, где применять эту внутреннюю синхронизацию по мере развития вашего класса.

Ответ 3

На этом сайте четко указано различие между ReentrantLock и синхронизированным ключевым словом в Java. Я просто копирую и вставляю оттуда.

http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

1) Еще одно существенное различие между ReentrantLock и синхронизированным ключевым словом - справедливость. синхронизированное ключевое слово не поддерживает справедливость. Любой поток может получить блокировку после освобождения, без предпочтения можно указать, с другой стороны, вы можете сделать ReentrantLock честным, указав свойство справедливости, создав экземпляр ReentrantLock. Свойство Fairness обеспечивает блокировку до самой длинной очереди ожидания в случае разглашения.

2) Вторая разница между синхронизированной и реентерабельной блокировкой - метод tryLock(). ReentrantLock предоставляет удобный метод tryLock(), который приобретает блокировку только в том случае, если она доступна или не удерживается каким-либо другим потоком. Это уменьшает блокировку потока, ожидающего блокировки в приложении Java.

3) Еще одна заслуживающая внимания разница между ReentrantLock и синхронизированным ключевым словом в Java - это возможность прерывать Thread во время ожидания Lock. В случае синхронизированного ключевого слова поток может быть заблокирован в ожидании блокировки в течение неопределенного периода времени, и не было никакого способа контролировать это. ReentrantLock предоставляет метод lockInterruptibly(), который может использоваться для прерывания потока, когда он ждет блокировки. Аналогично tryLock() с таймаутом может использоваться для таймаута, если блокировка недоступна в течение определенного периода времени.

4) ReentrantLock также предоставляет удобный метод для получения списка всех потоков, ожидающих блокировки.