Ist es sicher, write
auf Java FileOutputStream
-Objektformular mehrere Threads aufzurufen? Wird die Ausgabe korrekt serialisiert?
Klarstellung:
In meinem Fall enthält der Klassenlogger eine FileOutputStream-Referenz, und mehrere Threads können logger write aufrufen, die die Ausgabe formatiert und FileOutputStream write aufruft.
Sollte ich meine Logger-Schreibmethode synchronisieren, um sicherzustellen, dass die Nachrichten von mehreren Threads nicht gemischt sind?
Eine Datei kann nicht mehrmals in write-mode
geöffnet werden, daher lautet die Antwort nein.
Nachdem Sie Ihre Bearbeitung gesehen haben, sollten Sie die Synchronisation in Ihren Logger einführen, um sicherzustellen, dass auf den Stream nur von jeweils einem Thread zugegriffen wird. Nur ein Vorschlag, warum gehst du nicht für Log4J ? Es behandelt bereits Ihren Anwendungsfall.
Hier ist eine einfache Implementierung eines synchronisierten Loggers mit dem Java FileChannel. In diesem Beispiel sind Protokollmeldungen auf 1024 Byte beschränkt. Sie können die Protokollnachrichtenlänge anpassen, indem Sie den BUFFER_SIZE-Wert ändern.
%Vor%So würden Sie es verwenden:
%Vor%Nein. Java unterstützt nicht das Streamen von mehreren Threads zu demselben Stream.
Wenn Sie Threaded-Streams verwenden möchten, besuchen Sie diese Website: Ссылка
Er erklärt die Dinge gut und hat einen Beispielcode für ein ThreadedOutputStream
, der das macht, was Sie wollen.
Wenn Sie weiterbestellen möchten (dh Nachricht 1 im Ausgabestream kam vor Nachricht 2), müssen Sie den Stream sperren. Dies wiederum verringert die Nebenläufigkeit. (Alle Threads werden in die Warteschlange der Sperre / Semaphore eingereiht und warten dort, bis der Stream für sie verfügbar wird)
Wenn Sie nur an einem Stream gleichzeitig schreiben möchten und sich nicht um die Reihenfolge kümmern, können Sie Puffer für jeden Thread haben. Jeder Thread schreibt in seinen eigenen Puffer. Wenn der Puffer voll ist, erwirbt er eine Sperre (die möglicherweise auf die Sperre warten muss) für den Datenstrom und leert seinen Inhalt in den Datenstrom.
Bearbeiten: Ich habe gerade festgestellt, dass, wenn Sie sich für die Reihenfolge interessieren und immer noch Multi-Threading wollen, wenn Sie auch die Zeit im Ausgabestrom im Unix-Format schreiben (als lang). Nachdem der Stream in einen anderen Container geleert wurde, kann der Inhalt nach Zeit sortiert werden und Sie sollten eine geordnete Datei haben.