Java: кэширование энергонезависимых переменных разными потоками

Ситуация следующая:

  1. У меня есть объект с множеством сеттеров и геттеров.
  2. Экземпляр этого объекта создается в одном конкретном потоке, где все значения установлены. Сначала я создаю «пустой» объект, используя оператор new, и только затем вызываю некоторые методы установки, основанные на некоторой сложной устаревшей логике.
  3. Только после этого этот объект стал доступным для всех других потоков, использующих только геттеры.

Вопрос: Должен ли я сделать все переменные этого класса изменчивыми или нет?

Проблемы:

  • Создание нового экземпляра объекта и установка всех его значений разделен во времени.
  • Но все остальные темы не знают об этом новый экземпляр, пока не будут установлены все значения. Таким образом, другие потоки не должны иметь кеш не полностью инициализированного объекта. Не так ли?

Примечание: Я знаю о шаблоне компоновщика, но не могу применить его там по ряду других причин: (

EDITED: Поскольку мне кажется, что два ответа Матиаса и axtavt не очень хорошо совпадают, я хотел бы добавить пример:

Допустим, у нас есть класс foo :

class Foo {   
    public int x=0;   
}

и два потока используют его, как описано выше:

 // Thread 1  init the value:   
 Foo f = new Foo();     
 f.x = 5;     
 values.add(f); // Publication via thread-safe collection like Vector or Collections.synchronizedList(new ArrayList(...)) or ConcurrentHashMap?. 

// Thread 2
if (values.size()>0){        
   System.out.println(values.get(0).x); // always 5 ?
}

Как я понял, Матиас, он может распечатать 0 на некоторой JVM в соответствии с JLS. Как я понял axtavt всегда будет печатать 5.

Каково ваше мнение?

- С Уважением, Дмитрий

11
задан GPI 18 July 2016 в 09:30
поделиться