由于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(...)
直接调用任何方法时,以上方法才是安全的。