如果我有两个内存映射的缓冲区映射到同一文件,则是什么插入顺序?
-
21-12-2019 - |
题
我的问题是操作系统是否会尊重插入顺序(即最后写入,最后一个磁盘)或订单将是不可预测的。例如:
byte[] s1 = "Testing1!".getBytes();
byte[] s2 = "Testing2!".getBytes();
byte[] s3 = "Testing3!".getBytes();
RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
FileChannel fc = raf.getChannel();
MappedByteBuffer mbb1 = fc.map(MapMode.READ_WRITE, 0, 1024 * 1024);
mbb1.put(s1);
MappedByteBuffer mbb2 = fc.map(MapMode.READ_WRITE, mbb1.position(), 1024 * 1024);
mbb2.put(s2);
MappedByteBuffer mbb3 = fc.map(MapMode.READ_WRITE, mbb1.position() + mbb2.position(), 1024 * 1024);
mbb3.put(s3);
mbb1.put(s1); // overwrite mbb2
mbb1.put(s1); // overwrite mbb3
mbb1.force(); // go to file
mbb3.force(); // can this ever overwrite mbb1 in the file?
mbb2.force(); // can this ever overwrite mbb1 in the file?
.
它总是上次写的,最后一个或我缺少一些东西?
解决方案
我没有测试任何一个,所以我不知道。
但是,坦率地说,任何此订单都没有保证。
您有mbb.force()
方法,但这不是写入设备的唯一方法,而是确保它已经写了。
VM可以在感觉如下,使用它认为适合的任何时间表刷回设备,即自然地,依赖于极其平台(Linux上的行为可能与Windows上的行为不同,它可能甚至从Linux到Linux或Windows到Windows)。
似乎是您应该在内部协调,以确保只有一个读/写缓冲区映射到文件的特定区域,并管理冲突并重叠,而不是依赖于操作系统。
编辑:“由多个内存映射缓冲区完成的更改保证是一致的”
简单地,这意味着底层VM,一旦物理页面映射到一个过程,就会在执行的所有零样映射中共享该映射。线程问题只是由于CPU内存缓存和其他问题。所以,这保证所有映射都将在重叠缓冲区中看到相同的数据。但它不会在缓冲区实际写入设备时解决。这些点仍然是锗虫。
总的来说,如果正确处理任何多线程方面,那么您就不会有问题,并意识到您在底层缓冲区中看到的内容可能会“在脚下更改”。
不隶属于 StackOverflow