путать о видимости переменной потока Java - PullRequest
5 голосов
/ 19 июля 2011

Все примеры, которые я нашел, которые говорят о видимости, являются примерами с примитивным типом. То, что я хочу знать: если объект, который новый в куче, когда один поток вызывает свой метод, чтобы изменить свое состояние, без блокировки или синхронизации, другой поток увидит это изменение? Представьте себе объект Java.Colletion, один поток вызывает его метод add ()

Кто-то говорит, что для объекта в куче все еще есть проблема видимости, но JLS сказал: 17.4.1 Общие переменные Память, которая может быть разделена между потоками, называется общей памятью или кучей.

и http://www.artima.com/insidejvm/ed2/jvm2.html сказал: Стек Java потока хранит состояние вызовов метода Java (не собственного) для потока. Состояние вызова метода Java включает его локальные переменные, параметры, с которыми он был вызван, его возвращаемое значение (если оно есть) и промежуточные вычисления.

Так что я думаю, JVM не будет копировать объект, который в куче, в кеш процессора. Если это правильно, объект в куче не будет иметь проблемы с видимостью, потому что поток просто ссылается на объект в куче.

КСТАТИ Предположим, что есть параллельная проблема, когда один поток вызывает .add (). В обычном процессе изменения должны быть защищены с помощью блокировки, поэтому эта проблема не является проблемой. Но я просто хочу знать:)

Ответы [ 2 ]

3 голосов
/ 19 июля 2011

Ответ: «Нет, другой поток не будет обязательно видеть изменение в Коллекции», потому что (большинство) стандартных коллекций не являются поточно-ориентированными, то есть не имеютбезопасная публикация своего состояния.(Другой поток может видеть или не видеть изменения).

Именно поэтому был создан пакет java.util.concurrent - он обеспечивает поточно-ориентированные реализации java.util.Коллекции.

2 голосов
/ 19 июля 2011

Вы по-прежнему можете выполнять синхронизацию памяти без synchronized, если у вас есть volatile, атомарные переменные или другие параллельные контейнеры, которые обеспечивают семантику случай-до-100 * Однако, если вы ничего не сделаете, то ничего не гарантируется в отношении видимости памяти.

В вашем конкретном случае, если вы хотите вызвать add() для контейнера в одном потоке и сделать его видимым в другом без явной блокировки, тогда это будет работать, только если контейнер является параллельным (например, один из те, что в пакете java.util.concurrent), или синхронизированные (например, Collections.synchronizedList).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...