Skip to content

3. Synchronised

    synchronized (res){}

монитор захватывает объект например res это экземпляр какого либо класса и не отпускает пока не завершится код в скобках, т.е. не даёт его менять никакому потоку кроме текущего


synchronized в Java

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

Зачем нужно synchronized?

  1. Предотвращение состояния гонки: Гарантирует, что только один поток может выполнять критическую секцию кода.
  2. Согласованность данных: Обеспечивает, что данные остаются в согласованном состоянии при доступе из разных потоков.

Пример использования synchronized

class Counter {
    private int count = 0;

    // Синхронизированный метод
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

class MyThread extends Thread {
    private Counter counter;

    public MyThread(Counter counter) {
        this.counter = counter;
    }

    public void run() {
        for (int i = 0; i < 1000; i++) {
            counter.increment();
        }
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        MyThread thread1 = new MyThread(counter);
        MyThread thread2 = new MyThread(counter);

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println("Итоговое значение счётчика: " + counter.getCount());
    }
}

Объяснение примера

  1. Класс Counter: Содержит переменную count, которую мы хотим увеличивать из разных потоков. Метод increment() помечен как synchronized, что означает, что только один поток может выполнять этот метод в одно время.

  2. Класс MyThread: Наследует Thread и принимает объект Counter. Внутри метода run() мы вызываем метод increment() 1000 раз.

  3. Запуск потоков: В методе main() создаем два потока, которые работают с одним и тем же экземпляром Counter. Мы запускаем оба потока и ждем их завершения с помощью join().

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

Таким образом, использование synchronized помогает предотвратить проблемы, связанные с доступом нескольких потоков к общим ресурсам, обеспечивая корректность работы программы.


https://gitlab.com/synergy9980417/razdel2/2_4