我正在寫一個多線程的Java程序,其中每個線程可能需要將其標準輸出重定向到一個單獨的文件。每個線程都有自己的文件。是否可以在「每個線程」的基礎上重定向System.out,還是在所有線程中對System.out global進行更改?在多線程Java程序中,每個線程都有自己的System.out副本嗎?
回答
是否有可能重定向的System.out「每線程」的基礎上
上不,它是不可能的。 System.out
是靜態的,並且每個JVM在JVM最初引導時作爲系統類加載器的一部分加載。雖然推薦使用每線程正確的日誌記錄調用,但我認爲有一些原因讓你無法做到這一點。這種方式可能是第三方庫或其他代碼是使用System.out
。
你可以做的一件事(作爲一個激進的建議)是讓你自己的PrintStream
,代表ThreadLocal<PrintStream>
。但是你需要調用所有的方法來讓它每線程工作。
最後,如果你問這個是因爲你擔心併發,System.out
是PrintStream
所以它已經是在幕後,可以被多個線程安全地使用。
返回不同的'PrintStream'對象我目前正在尋找命名每個線程,並製作一個自定義的PrintStream,它需要一個Map
您可以使用java.util.logging(或其他日誌框架)和相應的格式化程序來記錄線程名稱。我強烈建議使用System.out的這種方法。 – Adamski 2012-04-04 16:35:16
我需要根據哪個線程正在運行將標準輸出重定向到一個變量位置。線程不輸出標準的「日誌」錯誤消息。我看着Java日誌記錄,我認爲這不適合我的問題。 – user1258361 2012-04-04 16:56:01
System.out
是靜態的,因此所有線程之間共享相同的實例。
你是對的,但不符合你的想法。當一個線程使用
System.out.println();
它採用參考System.out
的副本,而不是對象的引用這個副本。
這意味着所有線程通常會看到寫入輸出的相同對象。
注意:此字段不是線程安全的,如果您致電System.setOut(PrintStream)
如果使用此操作,則存在潛在的不良競爭情況,其中不同線程擁有不同的System.out本地副本。這不能用來解決這個問題。
是否有可能通過自己的實現是線程特定取代的System.out重定向的System.out「每線程」的基礎上
你可以做到這一點。即PrintStream的子類。我已經做了這個記錄,我希望每個線程的輸出是一致的而不是交錯的。例如想象一下,在兩個線程中同時打印兩個堆棧跟蹤。 ;)
你可以在啓動任何線程之前控制它,否則你不得不希望它無關緊要。你是什麼意思'男孩這是誤導'? – 2012-04-04 17:11:23
只有一個System.out。你所建議的是你改變System.out取決於線程,這不同於多個System.out。您的建議類似於說有8個CD-ROM和一個CD-ROM驅動器相當於有8個CD-ROM驅動器,因爲您可以在需要時切換CD。 CD可以切換出來嗎?是。和8個CD驅動器一樣嗎?沒有。 – user1258361 2012-04-04 17:33:14
我建議你改變System.out是一個組件,每個線程的基礎上做不同的事情。這與具有多個System.out值不同。我的評論是關於System.out的線程安全性,它允許多個線程由於競爭條件而看到不同的值,這是你不能使用的東西,只會是一個問題。我建議有一個8 CD轉換器,它對用戶來說是一個驅動器,例如有8個子目錄。 – 2012-04-04 17:46:44
是否有可能重定向的System.out「每線程」的基礎上
從Maia Company一些開發者提供了一個公共的實現,提供了一個「STDOUT」一個PrintStream的本文中的每個線程:「Thread Specific System.out」。
在它們的實現中,它們只覆蓋寫入方法flush,close和checkError。他們的情況似乎已經足夠了。
他們沒有「需要@Override所有的稱爲得到它每線程工作方法」作爲他的回答表示@Gray。
似乎這個鏈接已經死了,但是你可以在'org.apache.geronimo.gshell.support.gshell-io.SystemOutputHijacker'中找到類似的實現。 [Maven package](https://mvnrepository.com/artifact/org .apache.geronimo.gshell.support/gshell-io/1.0-alpha-2)和[源代碼瀏覽器](http://grepcode.com/file/repo1.maven.org/maven2/org.apache.servicemix。 kernel.gshell/org.apache.servicemix.kernel.gshell.core/1.1.0 /組織/阿帕奇/的geronimo/gshell/IO/SystemOutputHijacker.java) – 2016-07-04 08:53:14
- 1. 每個線程都不需要它自己的JVM副本嗎?
- 2. 每個'HttpRequest'在ASP.NET中都有自己的線程嗎?
- 3. 「每個JVM線程都有自己的程序計數器」是什麼意思?
- 4. 如何創建多個線程池(即多個執行程序,每個線程池都有一個線程)
- 5. java中有多線程的多線程
- 6. 運行多個線程(每個都有自己的應用程序上下文)並正常關機
- 7. 多個線程,每個線程都有不同的代理設置
- 8. 程序的每一行都有自己的地址嗎?
- 9. 副本列表,池,線程設置(1:N)的/每個線程本地存儲
- 10. Java,多個線程,每次只執行一個線程
- 11. 一個線程在iPhone應用程序中殺死另一個線程(兩個線程都是主線程)?
- 12. 如何鏈接非線程安全的庫,以便每個線程都有它自己的全局變量?
- 13. 每個進程都有自己的頁表嗎?
- 14. 每個進程都有自己的stdin,stdout和stderr嗎?
- 15. Java線程(多線程)
- 16. java編程和java單線程多線程問題(單線程與多線程)
- 17. Java中的多線程應用程序?
- 18. java中的多線程程序幫助
- 19. 子過程在自己的線程
- 20. 關於多線程的java多線程
- 21. 每個VCL表單都應該有自己的消息循環/泵線程?
- 22. 任何Java程序都至少有兩個線程?
- 23. 具有A類在自己的線程
- 24. 在自己的線程中運行每個Spring Scheduler
- 25. 一個循環在自己的線程
- 26. 多線程:線程獲取方法的自己的副本,但參數是共享
- 27. 具有單個更新程序線程的Java多線程緩存
- 28. java多線程應用程序:正在線程阻塞時間
- 29. Java線程程序
- 30. 多線程Java中
您可以使用[AspectJ](http://eclipse.org/aspectj) – 2013-03-20 17:43:43