Как вы думаете, лучший ли способ реализации части приобретения/приобретения пары в Java?Реализация приобретения для выпуска из Unsafe.putOrdered *()?
Я пытаюсь смоделировать некоторые действия в приложении my, используя классическую семантику release/получения (без StoreLoad
и без последовательной согласованности по потокам).
Существует несколько способов достижения приблизительного эквивалента хранилища в JDK. java.util.concurrent.Atomic*.lazySet()
и базовые sun.misc.Unsafe.putOrdered*()
являются наиболее часто цитируемыми подходами для этого. Однако нет очевидного способа реализовать загрузку.
В JDK API, которые позволяют
lazySet()
в основном используютvolatile
переменные внутри, так что их магазин-релизы спариваются с летучими нагрузками. Теоретически энергозависимые нагрузки должны быть более дорогими, чем загрузка, и не должны обеспечивать ничего большего, чем чистая загрузка в контексте предыдущего хранилища.sun.misc.Unsafe
не обеспечиваетgetAcquire()*
эквивалентовputOrdered*()
методов, даже если такие методы приобретают запланированы на предстоящий VarHandles API.Похоже, что это будет работать, это простая загрузка, а затем
sun.misc.Unsafe.loadFence()
. Это несколько обескураживает, что я не видел этого нигде. Это может быть связано с тем, что это довольно уродливый взлом.
P.S. Я хорошо понимаю, что эти механизмы не охвачены JMM, что их недостаточно для обеспечения последовательной согласованности и что созданные ими действия не являются действиями синхронизации (например, я понимаю, что они, например, прерывают IRIW). Я также понимаю, что хранилища-релизы, предоставленные Atomic*/Unsafe
, чаще всего используются либо для того, чтобы с легкостью обнулить ссылки или сценарии производителя/потребителя, как оптимизированный механизм передачи сообщений для некоторого важного индекса.
Спасибо, что нашли время, чтобы написать ответ! Он заполнен приятной общей информацией, но, хотя это полезно для некоторых людей, оно не предоставляет каких-либо новых идей, не присутствующих в вопросе, или каких-либо оправданий, почему использовать специально изменчивую нагрузку (в отличие от 'loadFence()' или что-то еще). –
Возможно, я не понимаю, что именно нужно. Почему он не отвечает? Не использовать ничего, кроме vread/'loadFence()'.Используйте volatile read, если вам нужна семантика/r для определенной переменной и 'loadFence()', если вам нужны только барьеры, например. для набора переменных или * до * чтения переменной, чтобы избежать определенного переупорядочения. Я отредактирую свой ответ, как только я пойму вас. Угадайте, что я могу удалить часть о no-ops и VH и добавить сравнение 'loadFence()' и vread, если вы этого хотите. – qwwdfsad
Вы получаете семантику получения из нестабильного чтения и ' loadFence() ', и теоретически энергозависимая нагрузка может быть более дорогостоящей на некоторых архитектурах, поскольку она должна быть частью действий синхронизации. Так что это не так просто, как «просто использовать волатильное чтение», по крайней мере, не без более существенных аргументов. Я предположил, что volatile read и 'loadFence()' являются единственными жизнеспособными опциями, но я все еще надеюсь, что кто-то откроет еще один интересный вариант. –