Can multiple threads see writes on a direct mapped ByteBuffer in Java?

前端 未结 7 2052
小鲜肉
小鲜肉 2020-12-08 07:31

I\'m working on something that uses ByteBuffers built from memory-mapped files (via FileChannel.map()) as well as in-memory direct ByteBuffers. I am trying to understand th

7条回答
  •  孤城傲影
    2020-12-08 08:06

    No. The JVM memory model (JMM) does not guarantee that multiple threads mutating (unsynchronized) data will see each others changes.

    First, given all the threads accessing the shared memory are all in the same JVM, the fact that this memory is being accessed through a mapped ByteBuffer is irrelevant (there is no implicit volatile or synchronization on memory accessed through a ByteBuffer), so the question is equivalent to one about accessing a byte array.

    Let's rephrase the question so its about byte arrays:

    1. A manager has a byte array: byte[] B_all
    2. A new reference to that array is created: byte[] B_1 = B_all, and given to thread T1
    3. Another reference to that array is created: byte[] B_2 = B_all, and given to thread T2

    Do writes to B_1 by thread T1 get seen in B_2 by thread T2?

    No, such writes are not guaranteed to be seen, without some explicit synchronization between T_1 and T_2. The core of the problem is that the JVM's JIT, the processor, and the memory architecture are free to re-order some memory accesses (not just to piss you off, but to improve performance through caching). All these layers expect the software to be explicit (through locks, volatile or other explicit hints) about where synchronization is required, implying these layers are free to move stuff around when no such hints are provided.

    Note that in practice whether you see the writes or not depends mostly on the hardware and the alignment of the data in the various levels of caches and registers, and how "far" away the running threads are in the memory hierarchy.

    JSR-133 was an effort to precisely define the Java Memory Model circa Java 5.0 (and as far as I know its still applicable in 2012). That is where you want to look for definitive (though dense) answers: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf (section 2 is most relevant). More readable stuff can be found on the JMM web page: http://www.cs.umd.edu/~pugh/java/memoryModel/

    Part of my answer is asserting that the a ByteBuffer is no different from a byte[] in terms of data synchronization. I can't find specific documentation that says this, but I suggest that "Thread Safety" section of the java.nio.Buffer doc would mention something about synchronization or volatile if that was applicable. Since the doc doesn't mention this, we should not expect such behavior.

提交回复
热议问题