假设两个线程同时使用单内存映射缓冲区(java.nio.channels.FileChannel.map())。
第一个线程是:
例如
ByteBuffer buffer = channel.map(READ_WRITE, 0, ...)
buffer.putShort((short) data.length);
buffer.put(data);读取线程是读取这些数据包:
short size = buffer.getShort();
byte[] bytes = new byte[size];
buffer.get(bytes);我不时地从BufferUnderflowException获得buffer.get(bytes),这是合理的,因为在这段天真的代码中显然存在竞争。阅读可以在写入大小之后,但在数据包之前进行。
问题是,写到mmap缓冲区是不稳定的吗?我能否安全地解决这个问题,只需在写线程中重新排序写入操作,这样在数据包本身之前就看不到数据包的长度,或者应该使用某种外部协调机制?
发布于 2018-08-02 07:40:13
这里没有任何与volatile相关的内容。你拥有的是两个需要原子化的书写。我不知道如何重新排序写操作将修复任何东西,而易失性不会使事情原子化。
您需要确保在头和数据写入之前不能执行读,因此需要外部同步。
值得注意的是,MappedByteBuffer在很大程度上依赖于底层文件系统和操作系统,因此您最好确保不编写依赖于本机行为的脆弱代码。
https://stackoverflow.com/questions/51647504
复制相似问题