Из Java-параллелизма на практике:
Объекты, которые не являются неизменяемыми, должны быть
безопасно опубликовано, что обычно
влечет за собой синхронизацию как
издательская и потребительская ветка.
Объект не публикуется безопасно, просто не публикуя его ссылку в конструкторе. То есть конструктор не обеспечивает необходимые отношения «происходит до». Таким образом, даже если вы не публикуете ссылку на объект в его конструкторе, у вас могут возникнуть проблемы с параллелизмом. Подробности и примеры см. В соответствующей главе в книге.
Чтобы сделать безопасную публикацию, авторы предлагают следующие способы:
Чтобы безопасно опубликовать объект, оба
ссылка на объект и
состояние объекта должно быть видно
другие темы одновременно.
правильно построенный объект может быть
безопасно опубликовано:
Инициализация ссылки на объект из
статический инициализатор;
Сохранение ссылки на него в
изменчивое поле или AtomicReference;
Сохранение ссылки на него в финале
поле правильно построено
объект; или
Сохранение ссылки на него в поле
это правильно охраняется замком.
В сущности, между конструкцией объекта и доступом к этому объекту другим потоком должна быть установлена правильная связь «происходит раньше».
Как отмечают авторы, объекты, которые передаются через безопасные коллекции потоков, также безопасно публикуются (например, элемент, переданный через рабочий поток через LinkedBlockingQueue и т. Д.).
Это правда, что сохранение значения в примитивных int
полях (но не в 64-битных полях, таких как long
) является атомарным, что означает, что вы не можете наблюдать «странное» значение, даже если вы обращаетесь к этому полю в не потокобезопасный способ из другого потока. Но когда объект еще не построен должным образом, могут произойти другие плохие вещи (честно говоря, я не знаю, что именно может произойти, но это, безусловно, не стоит пытаться).
Подводя итог, вам необходимо в любом случае безопасно опубликовать объект, после чего значение будет правильно установлено на 0, а объект будет создан правильно.