[英]Is PrintWriter thread-safe?
鑒於以下內容:
public class CConsole {
public static PrintWriter pw = new PrintWriter(System.out, true);
}
CConsole.pw.format("%d %d", x, y)
線程安全的? 也就是說,多個線程可以使用此調用嗎?它被描述為線程安全的位置。 我沒有在PrintWriter類描述中看到它,也沒有在format()方法描述中看到它。
這個問題沒有一個簡單的答案......
Writer
是PrintWriter
的超類,在其構造函數文檔中明確提到所有關鍵部分在Writer
實例本身或顯式指定的對象上同步。 因此Writer
顯然是線程安全的......
不幸的是, PrintWriter
子類文檔沒有明確地做出這樣的承諾。 它繼承了Writer
鎖對象,但無法知道任何其他或重寫的方法是否仍然是線程安全的。
另一方面,據我所知, Sun / OpenJDK PrintWriter
實現包含幾乎所有方法中的synchronized
塊。 但這似乎沒有明確記錄的行為。
我寧願玩它安全並假設PrintWriter
不是線程安全的,而不是依賴於未記錄的行為並且從長遠來看后悔...
這不是完全相同的問題,也沒有給出證據。
它還說PrintWriter是沒有資格的線程安全的,而另一個答案有資格。 在我看來,這需要澄清。
由於OP不理解(或者可能不相信)鏈接問題的答案,我將重申它們。
主要規范(即javadocs)不會聲明該類是否是線程安全的。
從閱讀源代碼可以清楚地看出,在所有相關操作都正確同步的意義上,它是線程安全的。
在上面的意義上,Oracle不太可能故意改變實現以使其成為非線程安全的。
但是,有些情況下PrintWriter
可能不完全是線程安全的:
如果多個線程使用單個PrinterWriter
,則結果可能是線程輸出的不可預測的交錯; 例如,如果他們使用印刷品而不是印刷品。
如果您有多個PrintWriter
對象包裝相同的基礎流,則可能由於PrintWriter
內部使用BufferedWriter
而出現問題。
如果您PrintWriter
事情可能會改變。
總之,當前的PrintWriter
實現(在Oracle / OpenJDK代碼庫中)是線程安全的,但在某些情況下仍需要小心。 還有可能其他第三方Java實現(即不是從OpenJDK源代碼樹派生)可能不是線程安全的。
涉及多個線程寫入相同底層流的應用程序的線程安全始終是細微的......
請注意@KazekageGaara發現的引用...
“ 多次寫入底層輸出流的
PrintWriter
所有方法都在內部處理同步,因此PrintWriter
對象是線程安全的。”
...來自O'Reilly教科書 - 馬克·格蘭德和喬納森·克努森的“Java基礎課程參考” 。 由於這不是正式的Sun / Oracle出版物,因此它絕不是最終的。
是的,它是線程安全的。 我不明白為什么有些人告訴它不是線程安全的。 它肯定有'lock'成員,它的方法在該lock對象下完全同步。
有人說PrintWriter.print方法不是線程安全的,但是錯了。 PrintWriter.print調用write(),這絕對是線程安全的。 我們都知道write方法在'lock'下是同步的。 因此,print方法是隱式/自然的線程安全的。
PrintWriter.println應該自己同步,因為它調用print()和println(),這兩者都是'獨立'線程安全的。
從這里開始 ,其中一行說:
PrintWriter多次寫入底層輸出流的所有方法都在內部處理同步,因此PrintWriter對象是線程安全的。
{
public void print(Object obj)
{
write(String.valueOf(obj));
}
/* Methods that do terminate lines */
}
打印不同步...
因此,如果您使用的是print方法,請寫下您自己的“My Writer”並進行同步。
要不然
如果你使用println()....然后它同步..
{
public void println(Object x) {
String s = String.valueOf(x);
synchronized (lock) {
print(s);
println();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.