简体   繁体   中英

Java mmap-buffer memory model

Suppose two threads working with single memory mapped buffer concurrently ( java.nio.channels.FileChannel.map() ).

First thread is:

  • writing the size of record;
  • writing the record itself;
  • repeat.

for example

ByteBuffer buffer = channel.map(READ_WRITE, 0, ...)

buffer.putShort((short) data.length);
buffer.put(data);

Reading thread is reading those packets:

short size = buffer.getShort();
byte[] bytes = new byte[size];
buffer.get(bytes);

From time to time I get BufferUnderflowException from buffer.get(bytes) which is reasonable because there is clearly race in this naïve code. Reading can happen after the size is written but before packet is.

The question is, does write to mmap buffer is volatile? Can I safely fix the problem just reordering write operation in writing thread, so length of the packet is never visible before the packet itself or some external coordination mechanism should be used?

There's nothing related to volatile in here. What you have is two writes which need to be atomic. I don't see how reordering write operations would fix anything, and volatile doesn't make things atomic.

You'll need to make sure that read can't be performed before the header and the data are written, so you'll need external synchronization for that.

It's also worth noting that MappedByteBuffer depends a lot on the underlying filesystem and OS, so you better make sure that you're not writing brittle code that relies on the native behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM