У меня проблема с параллелизмом Java.Да, я смотрел на вопросы с почти одинаковым названием, но все они, казалось, задавали немного разные вещи.Да, я прочитал Java-параллелизм на практике .Да, я понимаю, почему это ссылка на тему defacto .Да, я прочитал раздел, посвященный публикации полей в поточно-ориентированных классах.Да, я все еще собираюсь задать вопрос о параллелизме на Java, несмотря на то, что я знаю, что кто-то просто укажет мне на эту книгу.
Хотя это поставило меня в тупик - я знаю, что вы можете легко опубликоватьизменяемые примитивные поля потокобезопасным способом, обеспечивающие правильные порядки чтения / записи с изменчивостью и / или синхронизированным доступом, а также то, что 64-битным примитивам необходим атомарный доступ из-за отсутствия атомарности в его операциях чтения / записи.Я знаю об использовании блокировок фрагментов кода, которые должны выполняться для определенного «снимка» полей класса.Я полностью осведомлен об атомарном пакете с такими вкусностями, как AtomicLong <> и т. Д.
Но я все еще не понимаю, как публиковать не поточно-ориентированные объекты как поля в поточно-ориентированном классе.
Из того, что я вижу, как только вы возвращаете ссылку на него в геттере, вы предоставляете вызывающей стороне беспрецедентный доступ к содержимому объекта, который они могут использовать в любой момент.Кроме того, если вы предоставляете установщик, вы позволяете им устанавливать ссылку на объект для объекта, которым они могут потенциально управлять вне объекта, для которого он использует установщик.
Я не могу в любом случае отработатьсоставление поточно-безопасного класса из не поточно-безопасных объектов без превращения их всех в частные / защищенные и создания поточно-безопасных методов-обёрток в классе для всех методов, которые имеют все не поточно-безопасные объекты,пользователь класса может захотеть использовать.И это звучит просто как кошмарный кошмар.
Я имею в виду, если вы возвращаете AtomicReference <> для объекта в получателе, они могут просто использовать .get (), чтобы снова получить несинхронизированный доступ к нему.
Другой способ, который я рассмотрел, состоял в том, чтобы все геттеры возвращали новые копии не поточно-ориентированного объекта, основанного на старом, что означает, что модификации не будут иметь значения, с тем же применением к сеттерам.Но в Java есть безнадежно сложная система для клонирования объектов (мелкое копирование, глубокое копирование, специфическое копирование и т. Д.), Что меня как-то отталкивает.Кроме того, это настолько неэффективно, что это не будет быстрее, чем использование языка, который предназначен для неизменяемости, такого как Clojure.На самом деле, это, вероятно, будет намного медленнее, учитывая, что такие языки позволяют нескольким частям неизменяемых данных совместно использовать одни и те же данные за кулисами.
Итак, как мне составить поточно-безопасные классы опубликованных не поточно-безопасных объектовжизнеспособным образом?
Заранее спасибо.