Безопасная публикация неизменяемых структур данныхJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Безопасная публикация неизменяемых структур данных

Сообщение Anonymous »

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

Код: Выделить всё

public class DataStructure {

private final Map cache = new LinkedHashMap();

public Datum get(index i) { … }
public int size() { … }

public void eager() {
for (int i = 0; i < size(); i++)
get(i);
}

}
Метод нетерпеливый() не является потокобезопасным. Мое намерение состоит в том, чтобы объект был неизменяемым после возврата из функцииeater() и, следовательно, был потокобезопасным. Моя цель состоит в том, чтобы пользователи, которым нужна потокобезопасность, могли вызывать нетерпеливую() сразу после создания, прежде чем делиться объектом с другими потоками.
Однако я читаю Java Concurrency in Practice, и там упоминается, что безопасная публикация осуществляется через конечные поля. В этом классе нет окончательных полей.
Является ли этот класс потокобезопасным после вызова методаeater()? Если это не так, то как я могу изменить это так, как есть, не заплатив за счастливый путь, где нетерпеливость() никогда не вызывается и потокобезопасность не требуется?

Подробнее здесь: https://stackoverflow.com/questions/798 ... structures
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»