Die Kommunikation zwischen Prozessen ist nichts anderes als das Lesen und Schreiben von Dateien, die Kommunikation von Socket oder die Verwendung des gemeinsamen Speichers.
Java kann den Speicher nicht verwalten, aber tatsächlich wird er auch durch das Erstellen von Bilddateien erkannt.
Implementierung des gemeinsam genutzten Speichers in Java
Die in JDK1.4 bereitgestellte kartierte Bytebuffer -Klasse bietet uns eine bessere Möglichkeit, den gemeinsamen Speicher zu implementieren. Der Puffer ist eigentlich ein Speicherbild einer Festplattendatei. Änderungen zwischen den beiden bleiben synchronisiert, dh Änderungen der Speicherdaten werden in der Datenträgerdatei sofort reflektiert, wodurch die Implementierung des gemeinsamen Speichers effektiv gewährleistet wird.
Die Dateikanalklasse, die gemeinsam genutzte Speicher- und Festplattendateien verbindet, lautet: FileChannel. Diese Klasse wird JDK hinzugefügt, um den Zugriff auf externe Geräte (Dateien, Netzwerkschnittstellen usw.) zu vereinen und die Sicherheit des Multi-Threading-Zugriffs auf dieselbe Datei zu stärken. Beispielsweise werden Lese- und Schreibvorgänge in Lesen und Schreiben einheitlich. Hier erstellen wir es einfach, um gemeinsam genutztes Speicher zu erstellen, der einen Kanal zwischen gemeinsam genutztem Speicher und Datenträgerdateien festlegt.
Um eine Datei zu öffnen und einen Dateikanal zu erstellen, können Sie die Methode in der RandomAccessfile -Klasse verwenden, um GetChannel zu erhalten. Diese Methode gibt direkt einen Dateikanal zurück. Da die entsprechende Datei auf eine Zufallszugriffsdatei eingestellt ist, kann der Dateikanal zwei Vorgänge ausführen und auf der anderen Seite den Inhalt der Bilddatei nicht zerstören (wenn Sie eine Bilddatei direkt mit FileOutputStream öffnen, wird die Datei die Datei erfüllen Seien Sie die Größe auf 0, natürlich gehen alle Daten verloren). Wenn FileOutputStream und FileInputStream verwendet werden, können die Anforderungen des gemeinsam genutzten Speichers nicht idealerweise implementiert werden, da es gleichzeitig viel schwieriger ist, kostenlose Lesen und Schreibvorgänge zu implementieren.
Der folgende Code implementiert die obige Funktion, und seine Funktion ähnelt der MMAP -Funktion im UNIX -System.
// Erhalten Sie eine schreib- und randomanische Zugriffsdatei-Objekt RandomAccessfile Rafile = new randomAccessfile (Dateiname, "r"); // Erhalten Sie den entsprechenden Dateikanal Filchannel fc = rafile.getchannel (); // Erhalten Sie die tatsächliche Größe der Datei so Dieses Bild zum gemeinsamen Speicher int size = (int) fc.size (); // einen gemeinsam genutzten Speicherpuffer erhalten, der nur schreibgeschützt ist Mögliches Lesen und Schreiben von Random Access -Dateiobjekt Objekt Rafile = new randomAccessfile (Dateiname, "RW"); // Erhalten Sie den entsprechenden Dateikanal fc = rafile.getchannel (); // Erhalten Sie die tatsächliche Größe der Datei, damit sie abgebildet werden kann zu Shared Memory Size = (int) fc.size (); // einen gemeinsam genutzten Speicherpuffer erhalten, der gelesen und schreiben kann MAPBUF = FC.MAP (filechannel.map_rw, 0, Größe); // Header -Nachricht erhalten: Zugriff: Zugriff: Berechtigungsmodus = mapbuf.getInt ();
Wenn mehrere Anwendungen im Bild mit demselben Dateinamen genutzt werden, bedeutet dies, dass die mehrere Anwendungen dieselben Speicherdaten teilen. Diese Anwendungen können gleiche Zugriffsrechte an Dateien haben, und eine Anwendung aktualisiert die Daten in mehreren Anwendungen.
Um zu verhindern, dass mehrere Anwendungen gleichzeitig in den gemeinsam genutzten Speicher schreiben, können die Header -Informationen des gemeinsam genutzten Speichers Schreibbetriebsflags hinzugefügt werden. Die grundlegenden Header -Informationen dieses gemeinsamen Speichers sind mindestens:
intlänge; // Länge des gemeinsamen Speichers. Int -Modus; // Der aktuelle Zugriffsmodus dieses gemeinsam genutzten Speichers.
Die Headerinformationen des gemeinsamen Speichers sind die privaten Informationen der Klasse.
public boolean startWrite () {if (modus == 0) {// Wenn das Flag 0 ist, bedeutet dies, dass Modus = 1 geschrieben werden kann; MAPBUF.FLIP (); Shared Memory}} boolean stopwrite () {modus = 0; Die hier bereitgestellte Klassendatei mmap.java fasst die grundlegende Schnittstelle des gemeinsam genutzten Speichers zusammen, und die Leser können diese Klasse mit umfassenden Funktionen in eine Klasse erweitern, die sie benötigen.
Wenn die Anwendung, die einen Schreibvorgang ausführt, abnormal abgebrochen wird, kann der freigegebene Speicher der Bilddatei keine Schreiboperation mehr ausführen. Um das Schreibbetriebs -Prohibitions -Flag automatisch zu beseitigen, nachdem die Anwendung abnormal abgebrochen wurde, muss die laufende Anwendung über die beenden Anwendung informiert werden. In Multithread-Anwendungen können solche Effekte mit der Synchronisationsmethode erzielt werden, aber bei Multi-Process funktioniert die Synchronisation nicht. Es gibt viele Techniken, die in der Methode verwendet werden können, und hier finden Sie nur eine Beschreibung einer möglichen Implementierung: die Methode zur Verwendung von Dateisperrungen. Wenn eine Schreibspeicheranwendung Schreibberechtigungen für einen gemeinsam genutzten Speicher erhält, muss auch die Schreibberechtigungsflag der Headerinformationen beurteilt werden, sondern auch, ob eine temporäre Sperrdatei erhalten werden kann, wenn sie erhalten werden kann. Schreibberechtigungen der Headerinformationen werden geschrieben.
// Öffnen Sie eine temporäre Datei, beachten Sie, dass der gleiche freigegebene Speicher, der Dateiname der gleiche sein sollte, und Sie können das Suffix ".lock" nach dem freigegebenen Dateinamen hinzufügen. RandomAccessFile Fis = New Accessfile ("shm.lock", "rw"); // Dateikanal FileCannel Lockfc = fis.getchannel (); // Dateiausschließung erhalten. = lockfc.tryLock (); // Wenn leer, bedeutet dies, dass eine Anwendung die Sperre bereits besitzt, wenn (flock == null) {... // keine Schreibvorgänge ausführen kann} else {... // kann Schreibvorgänge nicht ausführen }Die Sperre wird automatisch veröffentlicht, nachdem die Anwendungsausnahme beendet ist. Dies ist genau die Methode, die hier benötigt wird.