Блокування в мові Java є механізмом, що дозволяє потоку захопити доступ до спільного ресурсу та утримувати його, поки блокування не буде звільнено. Це забезпечує синхронізований доступ до загальної пам’яті та запобігає стану гонки.
Монітор у мові Java є концепцією, пов’язаною з блокуваннями. Він представляє собою абстрактний об’єкт, з яким пов’язане блокування. До монітора може бути прив’язаний лише один потік, який володіє блокуванням і має до нього ексклюзивний доступ. Якщо інший потік намагається отримати доступ до заблокованого монітора, він буде заблокований і чекає, поки монітор не буде звільнений.
Ключове слово synchronized використовується для створення блокувань і моніторів у Java. Воно може бути використано в кількох формах, у тому числі для блокування методів, блоків коду або полів об’єктів. Коли потік заходить у заблокований код, він отримує доступ до монітора, пов'язаному з цим кодом, і інший потік не може отримати доступ до цього монітора, поки він не буде звільнений.Форма використанняОписsynchronized методБлокує доступ до цілого методу, що дозволяє тільки одному потоку виконувати його в будь-який момент часу.synchronized(this)Блокує доступ до блоку коду, виконання якого може бути здійснене тільки одним потоком одночасно.synchronized(об'єкт)Блокує доступ до блоку коду, виконання якого може бути здійснене тільки одним потоком одночасно. В якості об'єкта блокування може бути використаний будь-який об'єкт.synchronized static методБлокує доступ до цілого статичного методу, що дозволяє тільки одному потоку виконувати його в будь-який момент часу.synchronized(клас.class)Блокує доступ до блоку.код, виконання якого може бути здійснене лише одним потоком одночасно. Як об'єкт блокування використовується клас.Синхронізація коду за допомогою ключового слова synchronized є одним з основних механізмів у мові Java для забезпечення безпеки роботи з потоками. Однак слід бути обережним з його використанням, щоб уникнути проблем з продуктивністю та дедлоками.Приклади використання synchronizedПри роботі з потоками в мові Java, ключове слово synchronized відіграє важливу роль у забезпеченні правильної синхронізації доступу до спільних ресурсів. Розглянемо кілька прикладів використання synchronized для забезпечення безпеки роботи зі спільними даними.Приклад 1:Нехай у нас є клас Counter, який представляє лічильник з методами increment() і decrement(). Якщо ми не будемо використовувати synchronized, то можлива ситуація, коли два потоки одночасно збільшать лічильник, що призведе до невірних результатів. Щоб уникнути такої ситуації, можна використовувати synchronized для блокування звернень до методів increment() та decrement():Тепер доступ до методів increment() та decrement() буде здійснюватися надійно, оскільки тільки один потік зможе змінювати значення лічильника в один момент часу.Приклад 2:Іншим поширеним прикладом використання synchronized є робота з колекціями, які використовуються в кількох потоках. Наприклад, розглянемо наступний код:Тут ми використали блокування за об'єктом list під час додавання та видалення елементів. Таким чином, ми гарантуємо, що тільки один потік може змінювати список в один момент часу. Крім того, при поверненні елементів списку методом getList() ми створюємо його копію за допомогоюновий ArrayList<>(список), щоб уникнути можливої конкуренції за доступ до елементів.Приклади використання synchronized дозволяють забезпечити безпеку роботи з спільними даними в багатопотоковому середовищі та уникнути ситуацій гонки і непередбачуваного поводження програми.