Публикация не потокобезопасных полей объекта в поточно-ориентированном режиме - PullRequest
7 голосов
/ 17 июля 2011

У меня проблема с параллелизмом Java.Да, я смотрел на вопросы с почти одинаковым названием, но все они, казалось, задавали немного разные вещи.Да, я прочитал Java-параллелизм на практике .Да, я понимаю, почему это ссылка на тему defacto .Да, я прочитал раздел, посвященный публикации полей в поточно-ориентированных классах.Да, я все еще собираюсь задать вопрос о параллелизме на Java, несмотря на то, что я знаю, что кто-то просто укажет мне на эту книгу.

Хотя это поставило меня в тупик - я знаю, что вы можете легко опубликоватьизменяемые примитивные поля потокобезопасным способом, обеспечивающие правильные порядки чтения / записи с изменчивостью и / или синхронизированным доступом, а также то, что 64-битным примитивам необходим атомарный доступ из-за отсутствия атомарности в его операциях чтения / записи.Я знаю об использовании блокировок фрагментов кода, которые должны выполняться для определенного «снимка» полей класса.Я полностью осведомлен об атомарном пакете с такими вкусностями, как AtomicLong <> и т. Д.

Но я все еще не понимаю, как публиковать не поточно-ориентированные объекты как поля в поточно-ориентированном классе.

Из того, что я вижу, как только вы возвращаете ссылку на него в геттере, вы предоставляете вызывающей стороне беспрецедентный доступ к содержимому объекта, который они могут использовать в любой момент.Кроме того, если вы предоставляете установщик, вы позволяете им устанавливать ссылку на объект для объекта, которым они могут потенциально управлять вне объекта, для которого он использует установщик.

Я не могу в любом случае отработатьсоставление поточно-безопасного класса из не поточно-безопасных объектов без превращения их всех в частные / защищенные и создания поточно-безопасных методов-обёрток в классе для всех методов, которые имеют все не поточно-безопасные объекты,пользователь класса может захотеть использовать.И это звучит просто как кошмарный кошмар.

Я имею в виду, если вы возвращаете AtomicReference <> для объекта в получателе, они могут просто использовать .get (), чтобы снова получить несинхронизированный доступ к нему.

Другой способ, который я рассмотрел, состоял в том, чтобы все геттеры возвращали новые копии не поточно-ориентированного объекта, основанного на старом, что означает, что модификации не будут иметь значения, с тем же применением к сеттерам.Но в Java есть безнадежно сложная система для клонирования объектов (мелкое копирование, глубокое копирование, специфическое копирование и т. Д.), Что меня как-то отталкивает.Кроме того, это настолько неэффективно, что это не будет быстрее, чем использование языка, который предназначен для неизменяемости, такого как Clojure.На самом деле, это, вероятно, будет намного медленнее, учитывая, что такие языки позволяют нескольким частям неизменяемых данных совместно использовать одни и те же данные за кулисами.

Итак, как мне составить поточно-безопасные классы опубликованных не поточно-безопасных объектовжизнеспособным образом?

Заранее спасибо.

1 Ответ

4 голосов
/ 17 июля 2011

Если ссылка на небезопасные объекты переместилась в окружающие потоки - вы не можете ничего сделать, чтобы другие потоки не смогли изменить состояние, поэтому вы должны хранить ссылки в безопасности. Сделайте данные частными, добавьте методы, которые инкапсулируют доступ и модификацию, и сделайте поточно-ориентированные копии (да, клонирование громоздко), если вам когда-либо понадобится возвращать сложные объекты.

Попробуйте взглянуть на http://en.wikipedia.org/wiki/Law_of_Demeter принцип дизайна. цитата: В частности, объект должен избегать вызова методов объекта-члена, возвращаемого другим методом. Для многих современных объектно-ориентированных языков, которые используют точку в качестве идентификатора поля, закон можно сформулировать просто как «используйте только одну точку». То есть код a.b.Method () нарушает закон, а a.Method () - нет. В качестве простого примера, когда кто-то хочет выгуливать собаку, было бы глупо приказывать ногам собаки идти прямо; вместо этого один командует собакой и позволяет ей позаботиться о своих собственных ногах.

ps: боюсь, это открытый вопрос.

...