Конечно, если вы читаете и пишете ByteBuffer
в коде Java, используя методы Java, такие как put
и get
, тогда будет применяться отношение "до" между вашими изменениями в первом потоке, публикацией/потреблением и, наконец, последующим доступом во втором потоке< sup>0 ожидаемым образом. В конце концов, тот факт, что ByteBuffer
поддерживается памятью "вне кучи", является просто деталью реализации: он не позволяет методам Java в ByteBuffer
нарушать контракт модели памяти.
Все становится немного туманным, если вы говорите о записи в этот байтовый буфер из собственного кода, который вы вызываете через JNI или другой механизм. Я думаю, что пока вы используете обычные хранилища (т. е. не временные хранилища или что-то, что имеет слабую семантику, чем обычные хранилища) в вашем собственном коде, на практике все будет в порядке. В конце концов, JMV внутренне реализует сохранение в куче памяти с помощью одного и того же механизма, и, в частности, методы типа get
и put
будут реализованы с обычными загрузками и сохранениями. Действие публикации, которое обычно включает в себя некоторый тип хранилища выпуска, будет применяться ко всем предыдущим действиям Java, а также к хранилищам внутри вашего собственного кода.
Вы можете найти некоторые -td10427.html" rel="nofollow noreferrer">экспертное обсуждение в списках рассылки параллелизма более или менее по этой теме. Точный вопрос заключается в следующем: «Могу ли я использовать блокировки Java для защиты буфера, доступ к которому осуществляется только собственным кодом», но основные проблемы в значительной степени такие же. Вывод кажется согласующимся с вышеизложенным: если вы в безопасности, если вы выполняете нормальную загрузку и сохраняете в обычную область памяти1. Если вы хотите использовать более слабые инструкции, вам понадобится забор.
0 Это было немного длинное, вымученное предложение, но я хотел прояснить, что существует целая цепочка событий-до пар, которые должны быть правильно синхронизированы, чтобы это работало: ( A) между записью в буфер и хранилищем публикации в первом потоке, (B) хранилищем публикации и потребляющей нагрузкой (C) потребляющей загрузкой и последующими операциями чтения или записи вторым потоком. Пара (B) находится исключительно в Java-стране, поэтому следует обычным правилам. Тогда вопрос в основном заключается в том, подходят ли (A) и (C), которые имеют один «родной» элемент, также хорошо.
1 Нормальный в этом контексте более или менее означает тот же тип области памяти, что и Java, или, по крайней мере, один с строгими гарантиями согласованности в отношении типа памяти. Ява использует. Вы должны приложить все усилия, чтобы нарушить это, и, поскольку вы используете ByteBuffer
, вы уже знаете, что область выделена Java и должна играть по обычным правилам (поскольку методы уровня Java на ByteBuffer
должны работать в как минимум в соответствии с моделью памяти).
person
BeeOnRope
schedule
01.11.2017
Buffer
javadoc, в котором говорится, что буферы небезопасны для использования несколькими параллельными потоками. Если буфер должен использоваться более чем одним потоком, доступ к буферу должен контролироваться соответствующей синхронизацией. - person SpaceTrucker   schedule 01.11.2017