Поток операционной системы не является потокобезопасным (это утверждение не имеет большого смысла, но в основном операционная система не гарантирует соблюдение предполагаемой атомарности вашего кода).
Проблема состоит в том, что два элемента данных связаны и, следовательно, должны быть синхронизированы, действительно понимает только ваше приложение.
Например, представьте, что вы определяете класс ListOfIntegers
, который содержит массив int и подсчет числа элементов, используемых в массиве. Эти два элемента данных связаны, и способ их обновления должен быть скоординирован, чтобы гарантировать, что если к объекту обращаются два разных потока, они всегда обновляются согласованным образом, даже если потоки обновляют их одновременно. Только ваше приложение знает, как связаны эти элементы данных. Операционная система не знает. Это всего лишь две части памяти. Вот почему вам необходимо реализовать потокобезопасность (используя синхронизацию или тщательно упорядочивая способ обновления полей).
«Модель памяти» Java довольно близка к аппаратной модели. Есть стек для примитивов, а объекты размещаются в куче. Обеспечивается синхронизация, чтобы позволить программисту заблокировать доступ к общим данным в куче. Кроме того, существуют правила, которым должен следовать оптимизатор, чтобы оптимизация не нарушала установленную синхронизацию.