2015-05-27 2 views
6

Можно ли использовать квалификатор :volatile-mutable с deftype в однопоточной программе? Это продолжение до this question, this one и this one. (Это вопрос Clojure, но я добавил тег «Java», потому что Java-программисты также могут получить информацию об этом.)Риски изменчивых переменных полей в однопоточных контекстах?

Я обнаружил, что могу добиться значительного повышения производительности в программе, которую я работая в систему с помощью :volatile-mutable полей в deftype, а не атомов, но я волнуюсь, потому что для deftype строка документации говорит:

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

В самом деле, семантика и последствия :volatile-mutable являются не сразу очевидны для меня.

Однако глава 6 из Clojure Программирование, по Эмерик, Карпер и Гранд говорит:

«Летучие» здесь имеет то же значение, что и летучего модификатора поля в Java: чтение и запись атомный и должен быть выполнен в заказе программы; то есть они не могут быть переупорядочены компилятором JIT или процессором. Таким образом, летучие являются неудивительными и потокобезопасными, но несогласован и все еще полностью открыт для условий гонки.

Это подразумевает, что до тех пор, как доступ к одному летучим изменяемому deftype поля все имеет место в одном потоке, нет ничего особенного беспокойства. (Nothing special, в котором мне все еще нужно быть осторожным, как я обрабатываю состояние, если я могу использовать ленивые последовательности.) Поэтому, если ничто не вводит параллелизм в мою программу Clojure, не должно быть никакой особой опасности для использования deftype с :volatile-mutable.

Верно ли это? Какие опасности я не понимаю?

+2

Если у вас есть один поток java, а 'volatile' имеет то же значение, что и volatile java, вам вообще не нужно' volatile'. – ZhongYu

+0

атомарность - еще одна проблема. вы могли бы иметь проблемы параллелизма даже с одним потоком. Но я не знаком с Clojure, поэтому не могу комментировать. – ZhongYu

+0

bayou.io: ключевое слово volatile также гарантирует, что порядок вызовов вызовов изменчивых переменных не может быть переупорядочен. В некоторых случаях это может пригодиться, но я не могу думать об этом. –

ответ

3

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

Там нет никакого риска с точкой зрения безопасности потоков или атомарности при использовании летучего изменяемую (или просто изменяемое) поля в однопоточном контексте, потому что есть только один поток, так что нет никаких шансов из двух потоков писать новую значение в поле в одно и то же время или один поток, записывающий новое значение на основе устаревших значений.

Как уже указывалось в комментариях, вы можете просто использовать поле :unsynchronized-mutable, чтобы избежать затрат, вызванных изменчивостью.Эта стоимость исходит из того, что каждая запись должна быть , взятой в основной памяти вместо локальной памяти потока. См. this answer для получения дополнительной информации.

В то же время вы ничего не получаете, используя volatile в однопоточном контексте, потому что нет возможности иметь один поток, пишущий новое значение, которое не будет «видно» другим потоком, читающим одно и то же поле. Это то, для чего предназначена изменчивость, но она не имеет отношения к однопоточному контексту.

отметить также, что Clojure 1,7 введена volatile! предназначена для обеспечения «летучего ящика для управления состоянием», как быстрее альтернативы атома, с подобным интерфейсом, но без его сравнения и замены семантики. Единственное отличие при его использовании заключается в том, что вы вызываете vswap! и vreset! вместо swap! и reset!. Я бы использовал это вместо deftype с ^:volatile-mutable, если мне нужна изменчивость.

+0

Спасибо, среди прочего, я не знал о 'volatile!' И т. Д., И полезно знать о проблеме кеширования. – Mars

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