簡體   English   中英

PrintWriter是線程安全的嗎?

[英]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()方法描述中看到它。

這個問題沒有一個簡單的答案......

WriterPrintWriter的超類,在其構造函數文檔中明確提到所有關鍵部分在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();
         }
     }

}

不,它不是真正的線程安全。

這里查看PrintWriter.java中的write()方法

它們的寫入是在鎖定時同步的( 在此定義 - 這是Writer對象。如果它在此同步,它將是線程安全的,但在這種情況下它不是。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM