Нет. Модель памяти JVM (JMM) не гарантирует, что несколько потоков, изменяющих (несинхронизированные) данные, увидят изменения друг друга.
Во-первых, учитывая, что все потоки, обращающиеся к общей памяти, находятся в одной и той же JVM, тот факт, что доступ к этой памяти осуществляется через сопоставленный ByteBuffer, не имеет значения (не существует неявной изменчивости или синхронизации в памяти, доступной через ByteBuffer), поэтому вопрос эквивалентен вопросу о доступе к байтовому массиву.
Давайте перефразируем вопрос, чтобы он касался байтовых массивов:
- У менеджера есть байтовый массив:
byte[] B_all
- Создана новая ссылка на этот массив:
byte[] B_1 = B_all
и передана потоку T1
- Другая ссылка на этот массив создана:
byte[] B_2 = B_all
и передана потоку T2
Записывает ли в B_1
по потоку T1
замечается в B_2
по потоку T2
?
Нет, такие записи не гарантируются, если не будет явной синхронизации между T_1
и T_2
. Суть проблемы в том, что JIT JVM, процессор и архитектура памяти могут свободно изменять порядок доступа к памяти (не только для того, чтобы разозлить вас, но и для повышения производительности за счет кэширования). Все эти уровни ожидают, что программное обеспечение будет явным (через блокировки, энергозависимые или другие явные подсказки) о том, где требуется синхронизация, подразумевая, что эти слои могут свободно перемещать объекты, когда такие подсказки не предоставляются.
Обратите внимание, что на практике то, видите ли вы записи или нет, зависит в основном от аппаратного обеспечения и выравнивания данных на различных уровнях кэшей и регистров, а также от того, насколько «далеко» запущенные потоки находятся в иерархии памяти.
JSR-133 был попыткой точно определить модель памяти Java около Java 5.0 (и насколько я знаю, она все еще применима в 2012 году). Здесь вы хотите найти окончательные (хотя и плотные) ответы: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf (наиболее актуален раздел 2). Более читаемые материалы можно найти на веб-странице JMM: http://www.cs.umd.edu/~pugh/java/memoryModel/
Часть моего ответа - утверждение, что ByteBuffer
ничем не отличается от byte[]
в плане синхронизации данных. Я не могу найти конкретную документацию, которая говорит об этом, но я предлагаю, чтобы в разделе «Thread Safety» документа java.nio.Buffer упоминалось что-то о синхронизации или энергозависимости, если это применимо. Поскольку в документе об этом не упоминается, мы не должны ожидать такого поведения.