2010-11-04 5 views
8

Ich verwende MappedByteBuffer, um Dateilese-/schreibvorgänge zu beschleunigen(). Meine Fragen wie folgt:Müssen wir MappedByteBuffer.force() verwenden, um Daten auf die Festplatte zu schreiben?

  1. Ich bin nicht sicher, ob ich brauche .force() -Methode verwenden, um den Inhalt auf der Festplatte oder nicht zu spülen. Es sieht so aus, als ob ohne .force() die .getInt() immer noch perfekt funktionieren könnte (naja, da dies ein Speicher-gemappter Puffer ist, nehme ich an, dass .getInt() die Daten von der Platte holt, was bedeutet, dass die Daten in die Datenbank übertragen wurden bereits Platte.

  2. ist .force() -Methode eine blockierende Methode?

  3. eine blockierende Methode einen synchronisierten Block?

  4. Es gibt einen großen Unterschied in der Leistung mit oder ohne .force Aufruf () Was ist der Vorteil des manuellen Aufrufs von .force()? In welcher Situation sollten wir es verwenden? Ich gehe davon aus, dass die Daten immer noch auf die Festplatte hinter der Szene geschrieben werden, ohne sie aufzurufen.

  5. Wenn wir .force() aufrufen müssen, hilft das Aufrufen eines anderen Threads, die Leistung zu verbessern? Werden die Daten wegen Synchronisationsproblemen beschädigt?

    import java.io.FileNotFoundException; Import java.io.IOException; importieren Sie java.io.RandomAccessFile; Import java.nio.MappedByteBuffer; importieren Sie java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode;

public class Haupt {

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

Version des JDK? (Nicht, dass es wirklich so viel verändert hat) –

+0

Ich sehe nicht, welchen Unterschied das machen würde. – EJP

+0

Keine nach dem Blick auf die Javadoc :-) –

Antwort

3
  1. Sie sollten es nur anrufen, wenn Sie extreme Transaktionsanforderungen haben, das heißt Sie eine Datenbank zu implementieren. getInt() liest aus dem Speicher: Das Betriebssystem legt die Datei in den Speicher hinein und wieder heraus.

  2. Es ist nicht angegeben.

  3. Die Methoden werden synchronisiert, wenn dies angegeben ist. Es hat nichts damit zu tun, ob sie blockieren oder nicht.

  4. Siehe (1). Die Daten werden immer noch geschrieben, aber nach der Laune des Betriebssystems und nicht nach Ihrer.

  5. Ich bezweifle es, aber siehe (2), und ich bezweifle, dass Sie es überhaupt anrufen müssen, siehe (1).

+0

Gah, hätte deine Antwort zuerst kommen sehen, Entschuldigung dafür, dass ich fast dasselbe gesagt habe :). –

+0

Ich habe eine Frage, wenn ich Force() nicht aufrufen, gibt es irgendwelche Operation für diese Datei, wenn ich putInt oder getInt aufrufen? – Jaskey

2

OK, nehmen Sie meine Antwort mit einem Körnchen Salz (Ich bin kein Experte NIO)

1.) Die putInt(i, i) zum MappedByteBuffer (mbb), die im Speicher und der Betrieb ist schreiben Das System überträgt diesen Wert bei Bedarf in die eigentliche zugrunde liegende Datei (test.map).

Mit force() wird das Betriebssystem angewiesen, die Daten 'jetzt' zu übertragen (was nützlich sein kann, wenn Sie einen anderen Prozess haben, der aus dieser Datei lesen muss).

Ihre getInt(i) liest den Wert aus dem MappedByteBuffer (mbb), wenn Sie force() in der Weise verwenden, dass Sie dann wissen, dass Ihre Datei unter dem Hintergrund mit diesem Speicherpuffer synchronisiert ist).

Die Chancen sind Sie nicht force()

2.) Nicht sicher verwenden müssen, ich denke, es ist, als die Java 7 NIO.2 Sachen in der Lage zu anspielen beginnt diese Art der Sache zu tun auf nicht blockierende Weise. Ich recherchiere das momentan noch.

3.) Dies sind zwei getrennte Anliegen. Ich würde empfehlen, sich Doug Leas Buch anzusehen :-).

4.) Wie 1.), sagt force() dem Betriebssystem, 'jetzt' zu schreiben, sonst schreibt das OS, wenn es sich anfühlt.

+0

Ich habe eine Frage, die, wenn erzwungen wird, jede Auswirkung auf putInt() hat? , muss int int warten, bis force() abgeschlossen ist oder hat 'force()' Auswirkungen auf putInt()? – Jaskey

1

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

Kraft() ist nutzlos unter Windows. Ziemlich gruselig Bug.

+0

Zusätzlich zu Yaos Kommentar/Antwort, dass die Implementierung für die meisten Benutzer gut genug war, wurde der verknüpfte Fehler seit JRE 7 Build 118 behoben, aktuelle JVMs sind nicht betroffen. –

3

MappedByteBuffer.force() ist nicht nutzlos in Windows. Ich habe "Process Monitor" Tool von http://technet.microsoft.com/en-us/sysinternals/bb896645 verwendet, um den Dateizugriff zu überwachen. Entsprechend der Protokollierung ruft MappedByteBuffer.force() sofort Windows API WriteFile() in nicht zwischengespeicherten synchronen Modus auf. Die Zuverlässigkeit sollte ähnlich wie FileChannel.force() sein, die Windows API FlushFileBuffers() sofort aufrufen wird, um eine Datei zu schreiben. Daher ist MappedByteBuffer.force() für die meisten Arten von Verwendungen zuverlässig genug. Getestet auf Windows 7 64bit mit Java 1.6.0_24.

+1

Dies liefert keine Antwort auf die Frage. Um einen Autor zu kritisieren oder um Klärung zu bitten, hinterlasse einen Kommentar unter seinem Beitrag. - [Aus Bewertung] (/ review/low-quality-posts/10941104) – AtheistP3ace

+0

Ich hatte kein Recht, einen Kommentar unterhalb eines Beitrags hinzuzufügen, als ich diesen Beitrag schrieb. Deshalb habe ich einen neuen Beitrag erstellt. – Yao

Verwandte Themen