0

我的问题是操作系统是否会尊重插入顺序(即最后写入,最后写入磁盘)或者顺序将是不可预测的。例如:

    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?

它总是最后写的,最后写的还是我在这里遗漏了什么?

4

1 回答 1

2

我没有测试过这些,所以我不知道。

但是,坦率地说,不能保证任何这种排序。

你有mbb.force()方法,但这不是写入设备的唯一方法,它只是确保它已被写入。

虚拟机可以随时使用它认为合适的任何计划将页面刷新回设备,这自然是高度依赖于平台的(Linux 上的行为可能与 Windows 上的行为不同,甚至可能与Linux 到 Linux 或 Windows 到 Windows)。

似乎您应该在内部进行协调,以确保您只有一个读/写缓冲区映射到文件的特定区域,并以这种方式管理冲突和重叠,而不是依赖操作系统。

编辑:“多个内存映射缓冲区所做的更改保证是一致的”

简单地说,这意味着底层虚拟机一旦将物理页面映射到进程中,该映射就会在所有执行的各种映射中共享。线程问题仅仅是由于 CPU 内存缓存和其他问题。

因此,这保证了所有映射将在重叠缓冲区中看到相同的数据。但它没有解决缓冲区实际写入设备的时间。这些观点仍然密切相关。

总的来说,如果您正确处理任何多线程方面,听起来您不会有问题,并且请注意您在底层缓冲区中看到的内容可能“在您的脚下发生变化”。

于 2014-07-29T17:19:56.497 回答