powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Видимость изменения состояния переменной
9 сообщений из 9, страница 1 из 1
Видимость изменения состояния переменной
    #38546246
ngc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ngc
Гость
Привет.
Есть следующий код:
Код: java
1.
2.
3.
4.
class Foo {
    volatile Collection<> collection = Collections.emptyList();
}
final Foo foo = new Foo();


Thread1 | Thread2
foo.collection = new ArrayList<>(); | foo.collection.size();

Верно ли что Thread2 никогда не получит NPE при обращении к ссылке на коллекцию?
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546250
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, так как возможна следующая ситуация:
Код: java
1.
2.
3.
ref = reference(Foo);
ref.collection =  Collections.emptyList(); 
foo = ref;


А возможна и такая:
Код: java
1.
2.
3.
ref = reference(Foo);
foo = ref;
ref.collection =  Collections.emptyList(); 
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546251
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ngc ,
Не до конца дочитал ваш пост, но ответ не меняется :-) То, что вы выделили красным, все равно никаких гарантий не дает, NPE возможен, если:
1) Был указанный мною выше out-of-order в конструкторе;
2) Поток 2 сделал чтение до того, как поток 1 сделал запись.
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546265
ngc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ngc
Гость
cdtyjv,
Извините, не уточнил.
Код: java
1.
2.
3.
4.
5.
6.
class Foo {
    volatile Collection<> collection = Collections.emptyList();
    Foo() {
       collection = new ArrayList<>();
    }
}


как в таком случае будет выполнена публикация объекта?
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546267
ngc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ngc
Гость
cdtyjv,
к пункту 2 - опять же не уточнил - коллекция не изменяется.
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546366
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
out of order в конструкторе возможен, но присвоение final полю происходит вне конструктора

поэтому ситуация:

ref = reference(Foo);
foo = ref;
ref.collection = Collections.emptyList();


невозможна.

Кроме того, такая ситуация невозможна, даже если collection не волатильная, т.к. foo - финальное. После инициализации final поля с других потоков гарантировано доступны все поля, которые присваивались до присвоения финал-полю, и в него "вложены".

Другое дело, что в криво написаном коде можно умудриться сделать foo.collection.size() до того, как сделается final Foo foo = new Foo(), тогда конечно npe. А так мое ИМХО - npe не должно возникнуть.

еще вот тут интересно и почти по теме cheremin.blogspot.com/2011/12/final.html
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546389
ngc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ngc
Гость
chabapok,
Спасибо.
Допустим если не final но при этом collection is volatile, что тогда? Из JMM мне пока не очень понятно поведение.
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546399
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если foo не финал, то его присвоение можно реордерить. Тогда, существует опасность, что у вас из за реордеринга foo уже будет не null, но при этом конструирование foo еще не завершено и строчка volatile Collection<> collection = Collections.emptyList(); еще не выполнилась.

И если это произойдет, то тогда даже вот такое в другом потоке:

if (foo!=null) foo.collection.size();

потенциально приведет к npe.

Кроме того, в особо кривом случае, возможен случай что я написал выше -- само присваивание Foo foo = new Foo() не выполнилось и foo равно null, а вы уже из другого потока хотите получить foo.collection

Вот вам еще ссылка www.youtube.com/watch?v=qeCGjVf780s там про правила реордеринга

Оcновная идея -- записи в обычные поля не выносятся вперед записей волатилов. Назад выноситься могут.
таким образом, чтение из волатилов гарантирует видимость всех действий, которые были до записи в волатил этого значения.
...
Рейтинг: 0 / 0
Видимость изменения состояния переменной
    #38546400
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok,
Если поле файнал, то да, все безопасно, не заметил модификтор.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Видимость изменения состояния переменной
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]