2010-11-04 2 views
8

Я использую MappedByteBuffer для ускорения операций чтения/записи файлов(). Мои вопросы, как показано ниже:Нужно ли использовать MappedByteBuffer.force() для сброса данных на диск?

  1. Я не уверен, если мне нужно использовать .force() метод, чтобы очистить содержимое на диск или нет. Похоже, что без .force() функция .getInt() может работать отлично (ну, так как это буфер с отображением памяти, я предполагаю, что .getInt() извлекает данные с диска, что означает, что данные были сброшены в диск уже.

  2. является ли метод .force() метод блокировки?

  3. ли способ блокировки синхронизированный блок?

  4. Существует огромная разница в производительности с или без вызова .force (). Какая польза от вызова .force() вручную? В какой ситуации мы должны использовать его? Я предполагаю, что без его вызова данные будут записаны на диск за сценой.

  5. Если нам нужно позвонить в .force(), вызовет ли он из другого потока, чтобы улучшить производительность? Будет ли это повреждать данные из-за проблемы синхронизации?

    импорт java.io.FileNotFoundException; импорт java.io.IOException; import java.io.RandomAccessFile; импорт java.nio.MappedByteBuffer; импорт java.nio.channels.FileChannel; импорт java.nio.channels.FileChannel.MapMode;

общественного класса Main {

public static void main(String[] args) throws IOException { 
    System.out.println("start"); 

    RandomAccessFile raf = new RandomAccessFile("test.map", "rw"); 
    FileChannel fc = raf.getChannel(); 
    MappedByteBuffer mbb = fc.map(MapMode.READ_WRITE, 0, 2000000); 

    int total = 0; 
    long startTime = System.currentTimeMillis(); 
    for (int i = 0; i < 2000000; i += 4) { 
     mbb.putInt(i, i); 
     //mbb.force(); 
     total += mbb.getInt(i); 
    } 
    long stopTime = System.currentTimeMillis(); 

    System.out.println(total); 
    System.out.println(stopTime - startTime); 
    System.out.println("stop"); 
} 

}

+0

Версия JDK? (не то, чтобы это действительно сильно изменилось) –

+0

Я не вижу, какая разница. – EJP

+0

Нет, посмотрев на Javadoc :-) –

ответ

3
  1. Вы должны назвать это только если у вас есть крайние транзакционные требования, то вы реализуете базу данных. getInt() считывает из памяти: операционная система печатает файл в и из этой памяти.

  2. Не указано.

  3. Методы синхронизируются, если это указано. Это не имеет никакого отношения к тому, блокируются они или нет.

  4. См. (1). Данные по-прежнему будут записываться, но по прихоти операционной системы, а не по вашему.

  5. Сомневаюсь, но смотрю (2), и я сомневаюсь, что вам нужно вообще это назвать, см. (1).

+0

Гай, должен был сначала увидеть ваш ответ, извинившись за то, что сказал почти то же самое :). –

+0

У меня вопрос, если я не вызываю force(), есть ли какая-либо операция io для этого файла, когда я вызываю putInt или getInt? – Jaskey

2

ОК, возьмите мой ответ с зерном соли (я не NIO эксперт)

1.) putInt(i, i) запишет в MappedByteBuffer (МВВ), который находится в памяти и Operating Система передает это значение в фактический базовый файл (test.map), когда захочет.

Используя force(), операционная система передает данные «сейчас» (что может быть полезно, если у вас есть другой процесс, который необходимо прочитать из этого файла).

Вашего getInt(i) читает значение из MappedByteBuffer (МОВ), если вы используете force() таким образом, что вы, то вы знаете, что под капотом файл находится в синхронизации с этим буфером памяти).

Скорее всего, вам не нужно использовать force()

2.) Не уверен, что, я думаю, что это как Java 7 NIO.2 материал начинает намекать, чтобы быть в состоянии сделать такую ​​вещь в неблокирующем режиме. Я все еще изучаю это на данный момент.

3.) Это две отдельные проблемы. Я бы рекомендовал взглянуть на книгу Дуга Ли :-).

4.) Как указано в пункте 1.), force() сообщит ОС, чтобы написать «сейчас», иначе ОС будет писать, когда это будет похоже.

+0

У меня вопрос, что, когда сила выполняется, любой эффект на putInt()? , то put int должен дождаться force(), чтобы завершить действие или заставить force() 'повлиять на putInt()? – Jaskey

1

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6816049

сила() бесполезна в Windows. Довольно страшная ошибка.

+0

В дополнение к комментарию/ответу Яо о том, что реализация была достаточно хороша для большинства пользователей, связанная ошибка с тех пор была исправлена ​​в JRE 7 build 118, текущие JVM не затрагиваются. –

3

MappedByteBuffer.force() is не бесполезно в Windows. Я использовал инструмент «Process Monitor» от http://technet.microsoft.com/en-us/sysinternals/bb896645 для контроля доступа к файлам. Согласно протоколу, MappedByteBuffer.force() немедленно вызовет Windows API WriteFile() в Не кэшированный синхронный режим. Надежность должна быть такой же, как FileChannel.force(), которая сразу вызовет Windows API FlushFileBuffers() для записи файла. Поэтому MappedByteBuffer.force() достаточно надежна для большинства видов использования. Протестировано на Windows 7 64 бит с Java 1.6.0_24.

+1

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. - [Из обзора] (/ review/low-quality-posts/10941104) – AtheistP3ace

+0

Я не имел права добавлять комментарий после публикации, когда писал это сообщение. Вот почему я создал новый пост. – Yao

Смежные вопросы