Синхронизация метода Java
Есть такой код, здесь "FIRST!", "SECOND!" выводятся строго по очереди, если я убираю synchronized, то они выводятся в случайном порядке, из-за чего это происходит? Правильно ли я понимаю, что метод, помеченный, как синхронизированный, является критической секцией? То есть, доступ других потоков ограничен только в этот метод или это работает как-то на уровне класса?
public class Main {
public static void main(String[] args) throws InterruptedException {
CheckSynchronized x = new CheckSynchronized();
Thread one = new Thread(x::first);
Thread two = new Thread(x::second);
one.start();
two.start();
one.join();
two.join();
}
private static class CheckSynchronized {
public synchronized void first() {
for (int i = 0; i < 100; i++) {
System.out.println("FIRST!");
}
}
public synchronized void second() {
for (int i = 0; i < 100; i++) {
System.out.println("SECOND!");
}
}
}
}
Ответы (1 шт):
у каждого объекта есть то, что называется монитор. по сути это инструмент, блокирующий объект, используемый для корректной работы в многопоточной середе. но сам по себе он не работает, им нужно управлять. один из способов такого управления - ключевое слово synchronized, устанавливающее отношение happens before. простыми словами при вызове такого метода первым из потоков, который к нему обратился, захватывается этот самый монитор и, как следствие, объект блокируется для других потоков. пока работа с методом не закончится никто из потоков не сможет совершать-каких либо действий с данным объектом, все они будут ждать в очереди освобождения монитора потоком, который его захватил. при этом все потоки, которые будут работать с объектом после того, как монитор будет отпущен, смогут видеть все изменения, выполненные предыдущим потоком.
И самое последнее, что вам нужно знать. Все, что я рассказывал , касается нестатических методов. Как только вы добавите ключевое слово synchronized в статический метод, блокировки будут выполняться не с уровне объекта (у каждого объекта свой монитор, таким образом, если вы создаете 2 экземпляра одного и того же класса, синхронизированный метод захватывает монитор одного конкретного объекта и это никак не влияет на второй объект!), а на уровень класса!
p.s. разумеется, ответ не может описать всех подробностей, я шел на сознательные упрощения с целью сделать ответ более простым для понимания.