一尘不染

Java是System.out.println的多线程输出是否交错

java

如果多个线程在不同步的情况下调用System.out.println(String),输出是否可以交错?还是每行的写入都是原子的?该API只字不提同步的,所以这似乎是可能的,或者是由交错缓冲和/或虚拟机存储器模型等防止输出?

编辑:

例如,如果每个线程包含:

System.out.println("ABC");

保证输出是:

ABC
ABC

或者可能是:

AABC
BC

阅读 673

收藏
2020-03-01

共1个答案

一尘不染

由于API文档没有提及System.out对象的线程安全性,因此该PrintStream#println(String)方法 也不能假定它是线程安全的。

但是,特定JVM的基础实现完全有可能对该println方法使用线程安全函数(例如printf glibc),这样,实际上,将按照你的第一个示例保证输出(始终ABC\n如此ABC\n,永远不要散布字符)根据你的第二个示例)。但是请记住,有许多JVM实现,它们仅需遵守JVM规范,而无需遵循该规范之外的任何约定。

如果你绝对必须确保任何println调用都不会像你描述的那样散布,那么你必须手动强制执行互斥,例如:

public void safePrintln(String s) {
  synchronized (System.out) {
    System.out.println(s);
  }
}

当然,该示例仅是示例,而不应视为“解决方案”。还有许多其他因素需要考虑。例如,safePrintln(...)仅当所有代码都使用该方法并且没有System.out.println(...)直接调用任何方法时,以上方法才是安全的。

2020-03-01