Lombok @Synchronized — правильная синхронизация

Цикл статей «Project Lombok».

Следующая статья — «Lombok @Getter(lazy=true). Лень — это хорошо».
Предыдущая статья — «Lombok @SneakyThrows — храбро бросаем проверяемые исключения там, где их ещё никто не бросал».

Аннотация @Synchronized — это безопасный вариант модификатора synchronized. Так же как и synchronized, эта аннотация может быть использована только для статических методов и методов экземпляров классов. Он работает так же, как и ключевое слово synchronized, но ставит блокировку на другом объекте. Ключевое слово ставит блокировку на this, а аннотация — на поле с именем $lock, которое приватно. Если этого поля не существует, то оно создаётся. Если вы ставите аннотацию для статического метода, то аннотация блокирует статическое поле с именем $LOCK.

Вы можете создать эти объекты блокировки сами, если хотите. Поля $lock и $LOCK не будут генерироваться, если вы создадите их сами. Вы можете также выбрать для блокировки другое поле, которое можно указать в качестве параметра аннотации @Synchronized. При этом поля не будут созданы автоматически, и вы должны создать из сами, или возникнет ошибка.

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

С помощью Lombok

Чистая Java

Поддерживаемые ключи конфигурации

Lombok будет помечать любое использование @Synchronized предупреждением или ошибкой, если настроено.

Примечания

Если $lock и/или $LOCK генерируются автоматически, то поля инициализируются пустым массивом Object[], а не просто new Object() , как многие показывают этот паттерн в действии. Lombok делает так, потому что new Object()  НЕсериализуемый, а массив с нулевым размером сериализуемый. Поэтому использование @Synchronized не мешает сериализации вашего объекта.

Использование хотя бы одной аннотации @Synchronized для метода в вашем классе озанчает, что будет поле блокировки, но если вы позже удалите такие методы, то поля блокировки больше не будет. Это означает, что ваш автоматически вычисленный serialVersionUID изменится. Рекомендуется всегда добавлять serialVersionUID к вашим классам, если вы собираетесь их долго хранить с помощью объекта сериализации. Если вы сделаете это, то удаление аннотаций @Synchronized с ваших методов не сломает сериализацию.

Если вы хотите знать, почему поле автоматически не генерируется, когда вы выбираете своё имя для объекта блокировки: Потому что в противном случае опечатка в имени поля приведёт к очень трудно находимой ошибке.

 

Цикл статей «Project Lombok».

Следующая статья — «Lombok @Getter(lazy=true). Лень — это хорошо».
Предыдущая статья — «Lombok @SneakyThrows — храбро бросаем проверяемые исключения там, где их ещё никто не бросал».

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *