2012-06-17 23 views
7

Do sau:PrintWriter thread-safe?

public class CConsole { 
    public static PrintWriter pw = new PrintWriter(System.out, true); 
} 

CConsole.pw.format("%d %d", x, y) thread-an toàn không? Đó là, có thể nhiều chủ đề sử dụng lời gọi này và nó được mô tả ở đâu là an toàn luồng. Tôi không thấy nó trong mô tả lớp PrintWriter cũng như mô tả phương thức format().

+0

[Câu trả lời này] (http://stackoverflow.com/a/714424/1079354) có thể làm sáng tỏ một chút. – Makoto

+1

có thể trùng lặp của [Có phải là chuỗi InWriter của Java an toàn không?] (Http://stackoverflow.com/questions/714287/is-a-java-sockets-printwriter-thread-safe) –

+0

Tôi đã thấy điều đó. Nó không chính xác cùng một câu hỏi và không có bằng chứng được đưa ra. – H2ONaCl

Trả lời

8

Câu hỏi này không có câu trả lời đơn giản ...

Các Writer, đó là lớp cha của PrintWriter đề cập đến một cách rõ ràng trong tài liệu constructor của nó rằng tất cả các bộ phận quan trọng đồng bộ hóa hoặc trên Writer dụ chính nó, hoặc trên một cách rõ ràng đối tượng được chỉ định.Do đó, Writer rõ ràng là chỉ an toàn ...

Thật không may, tài liệu lớp con PrintWriter không hứa hẹn rõ ràng như vậy. Nó thừa hưởng đối tượng khóa Writer, nhưng không có cách nào để biết liệu có bất kỳ phương thức bổ sung hoặc ghi đè nào vẫn an toàn không.

Mặt khác, theo như tôi có thể nói, Sun/OpenJDK PrintWriter implementation chứa các khối synchronized theo mọi phương thức. Nhưng điều này dường như không phải là hành vi được ghi lại rõ ràng.

Tôi thà chơi nó an toàn và cho rằng PrintWriter không phải là thread-an toàn, vì dựa vào hành vi không có giấy tờ và hối tiếc này trong thời gian dài ...

0

Không, nó không thực sự an toàn.

Xem write() methonds trong PrintWriter.java here

Họ viết được đồng bộ hóa trên khóa (được định nghĩa here -. Đó là đối tượng Writer Nếu nó được đồng bộ về vấn đề này nó sẽ đã được thread-safe nhưng trong trường hợp này nó không phải là.

+0

bạn có ý nghĩa gì khi không an toàn cho chủ đề? những gì nó đã làm với khóa là gì? – Amareswar

5

Kể từ khi OP không hiểu (hoặc có thể không tin) câu trả lời cho câu hỏi liên quan, tôi sẽ trình bày lại cho họ.

  • các đặc điểm kỹ thuật chính (ví dụ: java tài liệu) không cho biết lớp học có an toàn hay không.

  • Rõ ràng là đọc mã nguồn an toàn theo luồng theo nghĩa là tất cả các hoạt động liên quan được đồng bộ hóa đúng cách.

  • Rất có khả năng Oracle sẽ cố tình thay đổi việc triển khai để làm cho nó không an toàn ... theo nghĩa ở trên.

  • Tuy nhiên, có trường hợp sử dụng nơi một PrintWriter sẽ không được hoàn toàn thread-safe:

    • Nếu một đơn PrinterWriter được sử dụng bởi nhiều chủ đề, kết quả có thể interleaving khó lường sản lượng từ chủ đề; ví dụ. nếu họ sử dụng in hơn là println.

    • Nếu bạn có nhiều PrintWriter s trên cùng một luồng cơ bản, có thể có sự cố do sử dụng nội bộ PrintWriter s của số BufferedWriter và do sự cố với khóa.

Nói tóm lại, hiện tại PrintWriter thực hiện (trong Oracle/codebase OpenJDK) là thread-an toàn, nhưng bạn vẫn cần phải cẩn thận trong một số tình huống, và đó cũng là khả năng triển khai khác có thể không an toàn cho luồng.


Lưu ý rằng các báo mà @KazekageGaara tìm thấy là từ một cuốn sách văn bản O'Reilly - "Java Lớp học cơ bản tham khảo" Mark Grand và Jonathan Knudsen. Vì nó không phải là một ấn phẩm Sun/Oracle chính thức, nó không phải là dứt khoát.

1

Taken từ here, trong đó một dòng nói:

Tất cả các phương pháp của PrintWriter viết nhiều lần vào dòng đầu ra bên dưới xử lý đồng bộ nội bộ, để các đối tượng PrintWriter là an toàn luồng.

+0

Liên kết bị hỏng ... –

+0

Nguồn gốc của báo giá này là "Tham chiếu Lớp cơ bản Java" Bởi Mark Grand và Jonathan Knudsen. Nó là một cuốn sách văn bản OReilly, không phải là một ấn phẩm chính thức của Sun/Oracle. Ergo, nó không phải là dứt khoát. –

1
{ 
public void print(Object obj) 
    { 

     write(String.valueOf(obj)); 
    } 

    /* Methods that do terminate lines */ 

} 

in không đồng bộ ...

Vì vậy, nếu bạn đang sử dụng phương pháp in, viết riêng ur "Writer của tôi" và đồng bộ hóa nó.

Hoặc Else

nếu bạn sử dụng println() .... Sau đó, nó đồng bộ ..

{ 

     public void println(Object x) { 
     String s = String.valueOf(x); 
     synchronized (lock) { 
      print(s); 
      println(); 
     } 
    } 

} 
1

Có, đó là thread-safe. Tôi không thể hiểu tại sao có một số người nói rằng nó không an toàn. Nó chắc chắn có thành viên 'khóa' và các phương pháp của nó được đồng bộ hoàn toàn theo đối tượng khóa đó.

Một số người nói rằng phương pháp PrintWriter.print không an toàn nhưng không đúng. PrintWriter.print calls write(), chắc chắn là an toàn chỉ. Chúng ta đều biết rằng phương pháp ghi được đồng bộ hóa dưới 'khóa'. Vì vậy, phương pháp in là hoàn toàn/tự nhiên thread-safe.

PrintWriter.println phải được đồng bộ bởi chính nó, bởi vì nó gọi print() và println(), cả hai đều là an toàn chủ đề 'độc lập'.

Các vấn đề liên quan