«Единственный способ творить великие дела – это любить то, что ты делаешь»
Веб Ученик


Synchronized в Java — это ключевое слово для обеспечения контроля доступа к общим ресурсам в многопоточной среде. Оно гарантирует, что в данный момент времени только один поток имеет доступ к блоку кода или методу, помеченному как synchronized.

Если поток начинает выполнять синхронизированный метод или блок кода, он получает «замок» на этот ресурс, и другие потоки не могут его использовать, пока первый поток не освободит замок.

Методы или блоки кода, которые изменяют общие данные, должны быть объявлены как synchronized, чтобы предотвратить одновременный доступ к общим ресурсам от разных потоков

Также ключевое слово synchronized обеспечивает атомарность операций и предотвращает конфликты между потоками.



Синхронизация

Синхронизация в Java — это процесс, который позволяет только одному потоку в определённый момент времени полностью выполнить заданную задачу

Синхронизация помогает предотвратить одновременный доступ к общим ресурсам от разных потоков и обеспечить целостность данных

Синхронизация метода

Чтобы синхронизировать метод в Java, нужно дописать «synchronized» перед названием метода

Если в сигнатуре метода в Java указано ключевое слово synchronized, то метод использует встроенную блокировку

При этом синхронизируется весь метод или класс. 

Java-код

public synchronized void myMethod() { 
    System.out.println("Hi I'm synchronized method!");
}

Java-код

Синхорнизация всего метода
    public synchronized void method (int index, String string) {
    }
Равносильна записи
    public void method (int index, String string) {
        synchronized(this) {
        }
    }

Синхронизация блока кода

При создании синхронизированного блока кода после оператора synchronized идёт объект-заглушка.

В качестве объекта может использоваться только объект какого-нибудь класса, но не примитивного типа.

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

Java-код

public class Main {
    private Object obj = new Object();
    public void doSomething() {
        // ...какая-то логика, доступная для всех потоков
        synchronized (obj) {
            // логика, которая одновременно доступна только для одного потока
        }
    }
}

Мьютекс и Монитор

Мьютекс — поле для синхронизации потоков. Есть у каждого объекта в Java. Неважно, какими классами пользоваться стандартными или собственными: у всех объектов всех классов есть мьютекс.

Это простейший Семафор, который может находиться в одном из двух состояний: true или false.

Монитор — это дополнительная надстройка над Мьютексом.

Блокирует объект именно монитор. Компилятор преобразует слово synchronized в несколько фрагментов кода - «под капотом» программы работает другой КОД.

Монитор в Java выражен с помощью слова synchronized. Реально работающий код, невидимый для программиста - это и есть Монитор.

Когда один тред (поток) заходит внутрь synchronized блока кода, JVM тут же блокирует Mьютекс синхронизированного объекта.

Mutex — это «флажок», переходящий к потоку, который в данный момент имеет право работать с общими ресурсами. Он исключает доступ остальных потоков к занятому участку памяти. Мьютексов в приложении может быть несколько, и они могут разделяться между процессами.

Java-код

public class Main {
   private Object obj = new Object();
   public void doSomething() {
       //...какая-то логика, доступная для всех потоков
       synchronized (obj) {
           //логика, которая одновременно доступна только для одного потока
       }
   }
}

В блоке кода, который помечен словом synchronized, происходит захват мьютекса объекта obj.

Семафор

Семафоры представляют еще одно средство синхронизации для доступа к ресурсу. В Java семафоры представлены классом Semaphore, который располагается в пакете java.util.concurrent. Для управления доступом к ресурсу семафор использует счетчик, представляющий количество разрешений. Если значение счетчика больше нуля, то поток получает доступ к ресурсу, при этом счетчик уменьшается на единицу.

Синхронизация в статических методах. Синхронизация по классу

Пример синхронизации статических методов.

Java-код

class MyClass {
	static int count;
	public static synchronized int getCount() {
		return count;
	}
}

У каждого объекта есть мьютекс. В примере не понятно, что будет выполнять роль мьютекса.

Ведь для вызова статического метода MyClass.getCount() - не нужны объекты.

Если требуется синхронизация в статических методах, то она осуществляется по классу.

Java-код

class MyClass {
	static int count;
	public static int getCount() {
		synchronized (MyClass.class) {
			return count;
		}
	}
}

Каждый загруженный в Java класс имеет соответствующий объект класса Class, представляющий этот класс. Монитор именно этого объекта используется для синхронизации статических методов.

При применении статических синхронизированных методов в Java происходит блокировка всего класса. Это означает, что только один поток может выполнять этот метод класса в одно и то же время.

Дополнительно. Объект МОНИТОР

В Java монитором может быть любой объект

Объект МОНИТОР - может быть взят как из вне, например вот так:

public final Object monitor = new Object()

Так и быть полем текущего класса. Монитор - это любой объект, любого типа.

Смысл объекта МОНИТОРА и ЕГО ЗАДАЧА - РЕГУЛИРОВАТЬ ДОСТУП В КРИТИЧЕСКУЮ СЕКЦИЮ МНОГОПОТОЧНОГО КОДА - в блок синхронизации.

Может ли поток блокировать мьютекс двух объектов?

Да, поток может блокировать мьютекс двух объектов.
Однако при таком подходе существует риск взаимоблокировки deadlock.

Например, если первый поток заблокирует один мьютекс, а второй — другой, оба потока зависнут в ожидании друг друга

Чтобы её избежать, во всех потоках мьютексы следует блокировать и освобождать в одном и том же порядке.

P.S.

Добрый день. Я изучаю JAVA. Некоторые темы мне довольно сложно освоить и усвоить. Поэтому я пишу такие вот статья с примерами. Делаю я это в большей степени для себя. Так мне проще понять и запомнить. Если кому-то пригодится – буду рад.

Этот материал используется исключительно в учебных целях и никакой коммерческой выгоды не несет. Текст частично взят из нейросети Яндекса, частично написан мною – материал берется из разных источников. Код писал сам, но за основу опять же брал какие-то уже существующие данные.

Если я где-то ошибся, что-то не правильно/не так описал – это нормально. Во-первых, я учусь, во-вторых, ни на что не претендую. Просьба это понимать.

Потоки в Java
Ключевое слово Synchronized СинхронизацияСинхронизация методаСинхронизация блока кодаМьютекс и МониторСемафорСинхронизация в статических методах. Синхронизация по классуДополнительно. Объект МОНИТОРМожет ли поток блокировать мьютекс двух объектов?
Способы создания потоков 1 способ. Наследование от класса Thread2 способ. Реализация интерфейса RunnableСоздание объекта Runnable с использованием анонимного классаОпределяем поведение потока с помощью лямбда-выраженияСоздание и запуск потока с использованием лямбда-выражения
Executor и ExecutorService Интерфейс ExecutorServiceExecutorService - реализация пула ПотоковСоздание пула потоков - Класс ExecutorsМетод execute() - выполнение задач в пуле потоковСоздание объекта Runnable с использованием анонимного класса
Интерфейс Callable Интерфейс Callable. Метод call() возвращает результатМетод submit() - задача в очереди на выполнениеFuture в Java - получить результат задачи. Метод get()Метод isDone - завершена ли задача?Методы shutdown() и shutdownNow()
Проблемы многопоточности Первый способ - блокирующая синхронизацияВторой способ: lock free или неблокирующая синхронизацияLock-free программирование. Пакет java.util.concurrent.atomicCompare-and-Set в Java. AtomicТретий способ Wait-free
Пакет java.util.concurrent Атомики в Java. Lock-free и thread-safe. Compare-and-Swap (CAS)Интерфейсы Future и CallableФреймворк ExecutorКласс ExecutorsОчереди в java.util.concurrentПродюсер и консьюмер в JavaКоллекции для работы в многопоточной средеThreadLocal и ThreadLocalRandomСинхронизаторы - синхронизация потоков
Тематические публикации
site.komp36.ru Как начать свое дело? Свой сайт «Укладка плитки» 9 000 руб. Лендинг адаптируется под любой вид отделочных работ, продажу товаров или услуг. Сайт поможет найти новых клиентов
site.komp36.ru Продающий лендинг «Установка и продажа окон» 9 000 руб. Одностраничный продающий сайт. Установка и продажа окон, установка дверей, перегородок. Заявки прямо с сайта
Последние статьи
Популярные статьи
Тематические публикации
site.komp36.ru Как начать свое дело? Свой сайт «Укладка плитки» 9 000 руб. Лендинг адаптируется под любой вид отделочных работ, продажу товаров или услуг. Сайт поможет найти новых клиентов
site.komp36.ru Продающий лендинг «Установка и продажа окон» 9 000 руб. Одностраничный продающий сайт. Установка и продажа окон, установка дверей, перегородок. Заявки прямо с сайта