Синхронизация в Java с помощью Synchronized

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

То есть они можно сказать выстраиваются в очередь чтобы воспользоваться куском кода в объекте. Смотри пример.

Пример программы:

public class SynchronizedExample { public static void main(String[] args) { // Объект ресурса (общий для потоков ресурс) CommonResource commonResource = new CommonResource(); // Запускаем 5 потоков, передавая в каждый из них // ресурс, общий для потоков. for (int i = 1; i < 6; i++) { Thread t = new Thread(new CountThread(commonResource)); t.setName("Thread " + i); t.start(); } // Когда выполнение кода одного из параллельных // потоков доходит до оператора synchronized, // доступ к блоку кода synchronized объекта // ресурса (commonResource) блокируется, и на // время его блокировки монопольный доступ к // блоку кода в этом объекте имеет только один // поток, который дошел до synchronized и который // произвел блокировку, и все прочие потоки, // которые используют commonResource будут ждать // пока поток, который первый дошел до блока // synchronized, закончит его выполнение. } } class CommonResource { int x; // Когда один из потоков доходит сюда, доступ // к блоку кода synchronized объекта // CommonResource блокируется, и другие потоки // которые дошли до synchronized останавливаются // и ждут, пока поток, дошедший сюда раньше них, // выполнит блок synchronized. Когда он все-таки // выполнил synchronized, в synchronized заходит // другой поток из очереди, и другие ждут, пока уже // этот другой поток выполнит код synchronized, // и так далее со всеми остальными потоками // в очереди. synchronized void increment() { x = 1; for (int i = 1; i < 5; i++) { System.out.printf("%s %d \n", Thread.currentThread().getName(), x); x++; try { Thread.sleep(700); } catch (InterruptedException e) {} } } } class CountThread implements Runnable { CommonResource res; CountThread(CommonResource res) { this.res = res; } public void run() { res.increment(); // вызываем синхронизированный метод } }

Вывод:

Благодаря этому потоки будут работать с ресурсом поочередно и от 1 до 4 сначала выведет первый дошедший до synchronized поток потом второй и так далее. Видим в консоли, что потоки выстроились в очередь в таком порядке – 1 5 2 4 3.

Synchronized static в Java

Разница между synchronized и synchronized static в Java. Как блокировка на уровне класса влияет на все объекты. Практические примеры и выводы.
Time to read: 15

Синхронизация с помощью Wait/Notify

Узнайте, как использовать wait/notify в Java для приостановки и возобновления потоков. Примеры кода и объяснение работы механизма межпоточной синхронизации.
Time to read: 9

Метод yield в Java

Метод yield() в Java: зачем поток уступает свое время другим? Разбор работы планировщика потоков и практическое применение с примером.
Time to read: 10