Ich schreibe ein Multithread-Java-Programm, bei dem jeder Thread seine Standardausgabe möglicherweise in eine separate Datei umleiten muss. Jeder Thread hätte seine eigene Datei. Ist es möglich, System.out auf einer "pro-Thread" -Basis umzuleiten oder sind Änderungen an System.out global über alle Threads hinweg?In einem Multithread-Java-Programm hat jeder Thread seine eigene Kopie von System.out?
Antwort
Ist es möglich, System.out auf einer "pro-Thread" Basis
Nein, es ist nicht möglich, umzuleiten. System.out
ist statisch und es gibt eine pro JVM, die als Teil des System-Classloaders geladen wird, wenn die JVM zu Beginn bootet. Obwohl natürlich die Verwendung geeigneter Protokollierungsaufrufe pro Thread empfohlen wird, nehme ich an, dass es Gründe gibt, warum Sie dies nicht tun können. Wahrscheinlich ist eine 3rd-Party-Bibliothek oder ein anderer Code, der auf diese Weise System.out
verwendet.
Eine Sache, die Sie (als eine radikale Anregung) tun könnten, ist Ihre eigenen PrintStream
, die an eine ThreadLocal<PrintStream>
delegiert. Aber Sie müssen @Override
alle Methoden aufrufen, um es per-Thread zu arbeiten.
Schließlich, wenn Sie das fragen, weil Sie über Gleichzeitigkeit besorgt sind, System.out
ist ein PrintStream
so ist es bereits synchronized
unter der Decke und kann von mehreren Threads sicher verwendet werden.
zurückgeben. Ich bin derzeit dabei, jeden Thread zu benennen und einen benutzerdefinierten PrintStream zu erstellen, der eine Map erstellt
Sie können java.util.logging (oder ein anderes Protokollierungsframework) mit einem geeigneten Formatierer verwenden, um den Namen des Threads zu protokollieren. Ich würde diesen Ansatz gegenüber der Verwendung von System.out dringend empfehlen. – Adamski
Ich muss die Standardausgabe an einen variablen Speicherort umleiten, basierend darauf, welcher Thread ausgeführt wird. Die Threads geben keine standardmäßigen "Protokoll" -Fehlermeldungen aus. Ich habe Java Logging angeschaut und finde es nicht passend für mein Problem. – user1258361
System.out
ist statisch und daher wird die gleiche Instanz zwischen allen Threads geteilt.
Sie haben Recht, aber nicht in der Art, wie Sie denken. Wenn ein Thread
verwendetSystem.out.println();
Es dauert eine Kopie der ReferenzSystem.out
, aber keine Kopie des Objekts dieser Referenzen.
Dies bedeutet, dass alle Threads normalerweise das gleiche Objekt zum Schreiben in die Ausgabe sehen.
Hinweis: Diese Felder sind nicht threadsicher und wenn Sie System.setOut(PrintStream)
aufrufen Wenn Sie dies verwenden gibt es eine potentielle, unerwünschte Race-Bedingung, wo verschiedene Threads unterschiedliche lokale Kopien von System.out haben. Dies kann nicht verwendet werden, um diese Frage zu lösen.
Ist es möglich, System.out auf einer „pro-Thread“ Basis
Sie können dies tun, indem Sie ersetzen System.out mit Ihrer eigenen Implementierung zu umleiten, die spezifisch ist fädeln. eine Unterklasse von PrintStream. Ich habe dies für die Protokollierung getan, wo ich wollte, dass die Ausgabe jedes Threads konsistent und nicht verschachtelt ist. z.B. Stellen Sie sich vor, Sie drucken zwei Stapelspuren in zwei Threads gleichzeitig. ;)
Du kannst es kontrollieren, bevor du weitere Threads startest, sonst musst du hoffen, dass es egal ist. Was meinst du damit? Junge, das ist irreführend? –
Es gibt nur ein einziges System.out. Was Sie vorschlagen, ist, dass Sie System.out abhängig vom Thread ändern, was nicht dasselbe ist wie mehrere System.out. Ihr Vorschlag entspricht der Aussage, dass 8 CD-ROMs und ein einzelnes CD-ROM-Laufwerk 8 CD-ROM-Laufwerken entsprechen, da Sie die CD bei Bedarf austauschen können. Können CDs ausgeschaltet werden? Ja. Ist es das gleiche wie mit 8 CD-Laufwerken? Nein. – user1258361
Ich schlage vor, Sie ändern die System.out zu einer Komponente, die auf einer Pro-Thread-Basis etwas anderes tut. Dies ist nicht dasselbe wie mehrere System.out-Werte. In meinem Kommentar ging es um die Thread-Sicherheit von System.out, die es mehreren Threads erlaubt, aufgrund einer Race Condition unterschiedliche Werte zu sehen, die Sie nicht verwenden können und die nur ein Problem darstellen. Ich schlage vor, einen 8-CD-Wechsler zu haben, der dem Benutzer als ein Laufwerk erscheint, z.B. mit 8 Unterverzeichnissen. –
Ist es möglich, System.out auf einer „pro-Thread“ Basis
Einige Entwickler von Maia Company zur Verfügung gestellt haben eine öffentliche Umsetzung eines Printumzuleiten, die ein „STDOUT“ bietet pro Thema in diesem Artikel: "Thread Specific System.out".
In ihrer Implementierung überschreiben sie nur Schreibmethoden, flush, close und checkError.Es scheint genug in ihrem Fall zu sein.
Sie tat nicht „Notwendigkeit alle Methoden @Override genannt, um es pro Thread zu arbeiten“, wie @Gray in seiner Antwort erklärt.
Scheint, dieser Link ist tot, aber Sie finden eine ähnliche Implementierung in 'org.apache.geronimo.gshell.support.gshell-io.SystemOutputHijacker' [Maven-Paket] (https://mvnrepository.com/artifect/org .apache.geronimo.gshell.support/gshell-io/1.0-alpha-2) und [Quellcode-Browser] (http://grepcode.com/file/repo1.maven.org/maven2/org.apache.servicemix. kernel.gshell/org.apache.servicemix.kernel.gshell.core/1.1.0/org/apache/geronimo/gshell/io/SystemOutputHijacker.java) –
Ist es möglich, System.out auf einer „pro-Thread“ Basis
Sie umleiten können sie alle auf Ihre Stellvertretung umleiten, die für verantwortlich sein wird ‚pro Thread‘ Logik.
Here is Beispiel für parallele JBehave-Tests mit eigener Dateiausgabe.
- 1. Hat jeder Benutzer eine eigene Datenbanktabelle?
- 2. Wie richte ich log4j-Eigenschaften so ein, dass jeder Thread in seine eigene Protokolldatei ausgibt?
- 3. in seine eigene Seite
- 4. k-Nächstliegende Nachbarn, in denen jeder Punkt seine eigene Klasse hat
- 5. In CSV-Datei jeden Buchstaben hat seine eigene Spalte
- 6. MATLAB: Streudiagramm von dem jeder Punkt eine eigene Farbe hat
- 7. Hat jeder Thread seinen eigenen Stack?
- 8. Hat jeder verwaltete Thread seinen eigenen entsprechenden nativen Thread?
- 9. Hat jede Instanz einer einschließenden Klasse eine eigene Kopie einer internen/nicht-statischen Klasse?
- 10. Wer hat eine Kopie von MSIINV.EXE?
- 11. Kann ein C# -Programm irgendwie seine eigene CPU-Auslastung messen?
- 12. MongoDB verschiebt Array von Unterdokumenten in seine eigene Sammlung
- 13. Wie kann ich ein "Partial" erstellen, das seine eigene Aktion hat?
- 14. UIButton nimmt seine eigene Größe Automatische Anordnung
- 15. Abbrechen Datei-Download von einem anderen Thread zu jeder Zeit
- 16. Hat jeder WinRT/Windows Core-Thread einen Dispatcher?
- 17. System.out Zeichencodierung
- 18. Umleiten von System.out zu JTextPane
- 19. Verwendet jemand Entity Framework? Es hat seine eigene linq-to-sql-Implementierung?
- 20. Erfordert GitHub, dass jeder Committer eine eigene Fork des Projekts hat?
- 21. So stellen Sie sicher, dass ein Klassenobjekt eine eigene Kopie hat, wenn geklont
- 22. Make Unterklasse hat ihre eigene Klasse Attribut
- 23. WCF-Dienstreferenz erzeugt seine eigene Vertragsschnittstelle wird nicht wiederverwenden Mine
- 24. Forking eines Child-Prozesses, der seine eigene Speicherkopie nicht verwendet
- 25. Chrome hat seine Konsole verloren?
- 26. Angular 2 RC4: Komponententestkomponente, die Abhängigkeitsinjektion hat einen Dienst, der seine eigene
- 27. Warum das umständliche Design von System.out?
- 28. Auf system.out, benötigt Klärung
- 29. Equivalent auf Objective C/Swift von Java Thread Variablen
- 30. Warum sollte Java Thread Variablen statisch seine
Sie können möglicherweise ein anderes 'PrintStream'-Objekt mit [AspectJ] (http://eclipse.org/aspectj) –