鉴于以下情况:
public class CConsole {
public static PrintWriter pw = new PrintWriter(System.out, true);
}
CConsole.pw.format("%d %d", x, y)
线程安全吗?也就是说,多个线程可以使用这个调用吗?它在哪里被描述为线程安全的。我在 PrintWriter 类描述和 format() 方法描述中都没有看到它。
鉴于以下情况:
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/OpenJDKPrintWriter
实现synchronized
在几乎所有方法中都包含块。但这似乎不是明确记录的行为。
我宁愿安全行事并假设它PrintWriter
不是线程安全的,也不愿依赖未记录的行为并从长远来看对此感到遗憾......
这不是完全相同的问题,也没有给出任何证据。
它还说 PrintWriter 是没有资格的线程安全的,而另一个答案有资格。在我看来,这需要澄清。
由于 OP 不理解(或者可能不相信)链接问题的答案,我将重申它们。
主要规范(即 javadocs)没有说明该类是否是线程安全的。
从阅读源代码可以清楚地看出,在所有相关操作都正确同步的意义上,它是线程安全的。
Oracle 不太可能故意更改实现以使其成为非线程安全的......在上述意义上。
但是,在某些用例中 aPrintWriter
可能不是完全线程安全的:
如果单个PrinterWriter
线程被多个线程使用,结果可能是线程输出的不可预知的交错;例如,如果他们使用 print 而不是 println。
如果您有多个PrintWriter
对象包装相同的底层流,则可能会由于PrintWriter
s 的内部使用而出现问题BufferedWriter
。
如果您将PrintWriter
.
总之,当前的PrintWriter
实现(在 Oracle/OpenJDK 代码库中)是线程安全的,但在某些情况下您仍然需要小心。其他第 3 方 Java 实现(即不是从 OpenJDK 源代码树派生的)也有可能不是线程安全的。
涉及多个线程写入同一底层流的应用程序的线程安全性总是有细微差别的......
请注意,@KazekageGaara 找到的引用...
“多次写入底层输出流的所有方法都在内部处理同步,因此对象是线程安全的。”
PrintWriter
PrintWriter
... 来自 O'Reilly 教科书 - Mark Grand 和 Jonathan Knudsen 的“Java Fundamental Classes Reference”。由于这不是 Sun / Oracle 的官方出版物,因此它没有任何权威性。
是的,它是线程安全的。我不明白为什么有些人说它不是线程安全的。它肯定有“锁定”成员,并且它的方法在该锁定对象下完全同步。
有人说 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 */
}
打印不同步...
因此,如果您使用打印方法,请编写您自己的“我的作家”并同步它。
要不然
如果你使用 println().. 那么它同步了..
{
public void println(Object x) {
String s = String.valueOf(x);
synchronized (lock) {
print(s);
println();
}
}
}