2014-01-15 2 views
5

Я изучал clojure lib, когда заметил, что изменчивое поле было аннотировано ^:unsynchronized-mutable. Mutable изменчиво, но я понятия не имел, что имел в виду синхронизирован часть, так что я прочитал docs, которые содержат:Каковы семантические последствия: volatile-mutable versus: unsynchronized-mutable?

Примечание хорошо, что изменяемые поля чрезвычайно трудно правильно использовать , и присутствуют только облегчают строительство более высоких конструкций уровня , таких как ссылочные типы Clojure, в Clojure . Они предназначены только для экспертов - если семантика и последствия of: volatile-mutable или: unsynchronized-mutable не являются незамеченными , вам не следует их использовать.

Я не мог получить нюанс: это говорит о том, что на практике не имеет значения, какую аннотацию изменчивости я выбираю, или что люди должны просто забыть об использовании изменяемых типов вообще?

И, ради любопытства, на более низком уровне абстракции, какова семантическая разница между ними?

Спасибо!

+3

Это, безусловно, говорят, что вы должны ** не ** использовать изменяемые поля. – Chuck

+0

Ссылка на исходный пример теперь сломана, но для тех, кто сейчас задается вопросом об источнике предупреждения, он находится в docstring для '' deftype' '(http://clojuredocs.org/clojure.core/deftype). – Mars

ответ

2

Ну, это не говорит о том, что «люди» должны забыть об использовании изменяемых типов. Это говорит о том, что любой человек, использующий их, должен знать разницу между несинхронизированными и изменчивыми (и подразумевая, что это не проблема, связанная с Clojure, поскольку в противном случае это будет объяснено в docstring). Я не знаю ни одного окончательного объяснения, но вы должны понимать модель памяти java, а также о потоковом и синхронизации в целом, прежде чем использовать изменяемые поля ложности Clojure.

У меня нет окончательной ссылки, но Википедия кажется, что у нее есть useful article по теме (nb я нашел ее только сейчас, и только ее снял).

+0

Я думаю, что это идет немного дальше, чем «любой человек, использующий их, должен знать разницу». Он это говорит, но он также говорит, что они существуют только для построения конструкций более высокого уровня, которые в большинстве случаев читают меня как очень сильное разочарование даже для тех, кто понимает последствия двух типов полей. – Chuck

1

Говорят, что если вы не понимаете разницу между и :unsynchronized-mutable, вы должны использовать ссылочные типы Clojure, а не напрямую с помощью изменяемых полей.

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

2

Это java-конструкции, поэтому вы не увидите их в любом месте документации clojure, кроме «не используйте это».

Чтение и запись являются атомарными для всех переменных, объявленных «изменчивыми».

Несинхронизированные поля - это обычные переменные переменные Java.

См https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

Практически говоря, это означает, что если у вас есть структура данных, когда несколько потоков доступ к данным для чтения или записи летучих целей всегда будет соответствовать; то есть вы всегда будете получать объект данных, который находится полностью или полностью после операции над этими данными.

Прошу прощения, если это не означает 100%; семантика - комплекс; ознакомьтесь с этим, если вы хотите получить более глубокое понимание: When exactly do you use the volatile keyword in Java?

tldr;

Летучие вещества менее эффективны, чем несинхронизированы; но он дает более качественные гарантии передачи данных.

Избегайте их обоих, если вы можете, но если вам нужно использовать один, вы, вероятно, хотите :volatile-mutable

Смежные вопросы