Найти в Дзене

Что такое synchronized и volatile. Как они связаны с многопоточностью?

Synchronized — это ключевое слово в Java, которое используется для управления доступом к общим ресурсам в многопоточных приложениях. Основная цель его использования — обеспечить, чтобы только один поток одновременно мог выполнять определённый блок кода или метод. Это помогает избежать состояний гонки (race conditions), когда несколько потоков пытаются одновременно изменить один и тот же ресурс, что может привести к некорректным результатам. Можно синхронизировать не весь метод, а только определённый блок кода внутри метода. Например: Внутри блока синхронизации можно использовать любой объект в качестве монитора. Volatile — это модификатор переменной в Java, который гарантирует, что значение переменной будет читаться и записываться непосредственно из основной памяти (main memory) и не будет кэшироваться потоками. Это важно в многопоточной среде, где одни потоки могут изменять значение переменной, а другие — читать её. Запись значения в переменную будет сразу видна всем другим потокам.
Оглавление

synchronized

Synchronized — это ключевое слово в Java, которое используется для управления доступом к общим ресурсам в многопоточных приложениях. Основная цель его использования — обеспечить, чтобы только один поток одновременно мог выполнять определённый блок кода или метод. Это помогает избежать состояний гонки (race conditions), когда несколько потоков пытаются одновременно изменить один и тот же ресурс, что может привести к некорректным результатам.

  • Блоки:

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

Например:

-2

Внутри блока синхронизации можно использовать любой объект в качестве монитора.

volatile

Volatile — это модификатор переменной в Java, который гарантирует, что значение переменной будет читаться и записываться непосредственно из основной памяти (main memory) и не будет кэшироваться потоками. Это важно в многопоточной среде, где одни потоки могут изменять значение переменной, а другие — читать её.

  • Если переменная объявлена как volatile, то:

Запись значения в переменную будет сразу видна всем другим потокам.
Чтение переменной будет всегда из основной памяти, а не из кэша процессора.

  • Пример использования:
-3

Связь с многопоточностью

  • Synchronized: Используется для управления доступом к общим ресурсам между потоками, предотвращая одновременное выполнение критического кода несколькими потоками.
  • Volatile: Используется для обеспечения видимости изменений переменной между потоками.

Взаимодействие volatile и synchronized

Оба механизма относятся к инструментам для работы с многопоточностью, но они решают разные задачи:

  • volatile только гарантирует видимость изменений переменной между потоками, но не обеспечивает атомарность операций. Например, если вам нужно увеличивать значение переменной на единицу, то volatile не поможет избежать состояния гонки, так как операция инкремента не атомарна.
  • synchronized гарантирует как видимость изменений, так и атомарность выполнения кода внутри синхронизированного блока.

Пример:

Предположим, у нас есть переменная int counter, которая увеличивается несколькими потоками.

  • Без синхронизации:
-4

Здесь возможны состояния гонки, так как counter++ состоит из нескольких операций (чтение, увеличение, запись).

  • С использованием synchronized:
-5

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

  • С использованием volatile:
-6

В этом случае volatile не решает проблему состояния гонки, так как операция counter++ всё ещё не атомарна. volatile только гарантирует, что значение будет актуально для других потоков, но не предотвращает состояния гонки.

Надеюсь, теперь стало понятно, как synchronized и volatile работают в контексте многопоточности и для чего они используются!

Про synchronized и volatile прочитайте также статьи Вопросы отсеивающего собеседования (с HR) на позицию автотестировщика java в Тинькофф (вопрос "К чему применяется volatile?") и Что такое потокобезопасность? Как её обеспечить в java?

-7

Не забудьте подписаться на канал, чтобы не пропустить полезную информацию: QA Helper - справочник тестировщика

Пишите в комментариях какой пункт было бы интересно рассмотреть более подробно.

Также будет интересно почитать: Вопросы которые задают на собеседовании тестировщикам