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

前端 未结 7 2049
小鲜肉
小鲜肉 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:02

    I would assume that direct memory provides the same guarantees or lack of them as heap memory. If you modify a ByteBuffer which shares an underlying array or direct memory address, a second ByteBuffer is another thread can see the changes, but is not guaranteed to do so.

    I suspect even if you use synchronized or volatile, it is still not guaranteed to work, however it may well do so depending on the platform.

    A simple way to change data between threads is to use an Exchanger

    Based on the example,

    class FillAndEmpty {
       final Exchanger exchanger = new Exchanger();
       ByteBuffer initialEmptyBuffer = ... a made-up type
       ByteBuffer initialFullBuffer = ...
    
       class FillingLoop implements Runnable {
         public void run() {
           ByteBuffer currentBuffer = initialEmptyBuffer;
           try {
             while (currentBuffer != null) {
               addToBuffer(currentBuffer);
               if (currentBuffer.remaining() == 0)
                 currentBuffer = exchanger.exchange(currentBuffer);
             }
           } catch (InterruptedException ex) { ... handle ... }
         }
       }
    
       class EmptyingLoop implements Runnable {
         public void run() {
           ByteBuffer currentBuffer = initialFullBuffer;
           try {
             while (currentBuffer != null) {
               takeFromBuffer(currentBuffer);
               if (currentBuffer.remaining() == 0)
                 currentBuffer = exchanger.exchange(currentBuffer);
             }
           } catch (InterruptedException ex) { ... handle ...}
         }
       }
    
       void start() {
         new Thread(new FillingLoop()).start();
         new Thread(new EmptyingLoop()).start();
       }
     }
    

提交回复
热议问题