Каков порядок вставки, если у меня есть два буфера с отображением памяти, сопоставленные с одним и тем же файлом?

Мой вопрос заключается в том, будет ли ОС соблюдать порядок вставки (т.е. последний записанный, последний на диск) или порядок будет непредсказуемым. Например:

    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?

Это всегда написано последним, последним или я что-то здесь упустил?


person Michelle Queen    schedule 29.07.2014    source источник
comment
В отсутствие какого-либо определения оно не определено. Вероятно, оба сопоставления будут одинаковыми, так что они оба просматривают один и тот же набор страниц, но это зависит от отдельных операционных систем.   -  person user207421    schedule 29.07.2014
comment
@EJP смотрите мой комментарий к ответу Уилла Хартунга.   -  person Michelle Queen    schedule 29.07.2014
comment
Я их уже читал. Ничего не меняет. Верьте во что хотите, но конкретики нет. NB «вероятно» — это опечатка iPad для слова «вероятно».   -  person user207421    schedule 29.07.2014


Ответы (1)


Я ничего из этого не проверял, поэтому не знаю.

Но, честно говоря, нет никаких гарантий ни на один из этих заказов.

У вас есть метод mbb.force(), но это не единственный способ записи на устройство, он просто гарантирует, что оно было записано.

Виртуальная машина может сбросить страницу обратно на устройство, когда ей захочется, используя любое расписание, которое она сочтет подходящим, что, естественно, сильно зависит от платформы (поведение в Linux может отличаться от поведения в Windows, оно может даже отличаться от Linux на Linux или Windows на Windows).

Похоже, что вы должны внутренне координировать свои действия, чтобы убедиться, что у вас есть только один буфер чтения/записи, сопоставленный с определенной областью файла, и управлять конфликтами и перекрытием таким образом, а не полагаться на операционную систему.

Изменить: «изменения, сделанные несколькими буферами с отображением памяти, гарантированно будут согласованными»

Проще говоря, это означает, что базовая виртуальная машина, после сопоставления физической страницы с процессом, это сопоставление используется во всех выполняемых сопоставлениях. Проблемы с потоками возникают просто из-за кэширования памяти процессора и других проблем.

Таким образом, это гарантирует, что все сопоставления будут видеть одни и те же данные в перекрывающемся буфере. Но это не относится к тому, когда буферы действительно будут записаны на устройство. Эти пункты по-прежнему актуальны.

В целом похоже, что у вас не будет проблем, если вы правильно обработаете какие-либо аспекты многопоточности и помните, что то, что вы видите в своем базовом буфере, может «измениться у вас под ногами».

person Will Hartung    schedule 29.07.2014
comment
Спасибо за помощь. Я нашел это: stackoverflow.com/a/9122606/3751417. Похоже, что если я нахожусь в одном потоке, изменения, сделанные несколькими буферами с отображением памяти, гарантированно будут согласованными, если я правильно понял. Любые комментарии? - person Michelle Queen; 29.07.2014
comment
Видел, как ты редактировал. Я думаю, что вы ошибаетесь здесь. Я склонен полагать, что если у меня есть два буфера с отображением памяти, сопоставленные с одним и тем же файлом, они будут использовать одно и то же пространство памяти, поэтому они НЕ будут наступать друг на друга, другими словами, если buffer2 записывает в то же место после того, как буфер1 записал в то же место, вы можете быть уверены, что данные буфера2 будут на диске, а не данные буфера1, при условии, что мы находимся в одном потоке. - person Michelle Queen; 29.07.2014