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
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();
}
}