System.out.println 的多线程输出是否交错 [英] Is multi-thread output from System.out.println interleaved

查看:44
本文介绍了System.out.println 的多线程输出是否交错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果多个线程在没有同步的情况下调用 System.out.println(String),输出是否可以交错?或者每一行的写入都是原子的?API 没有提到同步,所以这似乎是可能的,或者缓冲和/或 VM 内存模型等阻止了交错输出?

If multiple threads call System.out.println(String) without synchronization, can the output get interleaved? Or is the write of each line atomic? The API makes no mention of synchronization, so this seems possible, or is interleaved output prevented by buffering and/or the VM memory model, etc.?

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

For example, if each thread contains:

System.out.println("ABC");

是保证的输出:

ABC
ABC

或者可能是:

AABC
BC

推荐答案

由于 API 文档没有提到 System.out 对象 也没有 PrintStream#println(String) 方法你不能假设它是线程安全的.

Since the API documentation makes no mention of thread safety on the System.out object nor does the PrintStream#println(String) method you cannot assume that it is thread-safe.

但是,特定 JVM 的底层实现完全有可能对 println 方法使用线程安全函数(例如 printf on glibc) 这样,实际上,输出将根据您的第一个示例得到保证(总是ABC 然后 ABC ,不要在第二个例子中穿插字符).但请记住,有很多 JVM 实现,它们只需要遵守 JVM 规范,而不是该规范之外的任何约定.

However, it is entirely possible that the underlying implementation of a particular JVM uses a thread-safe function for the println method (e.g. printf on glibc) so that, in reality, the output will be guaranteed per your first example (always ABC then ABC , never interspersed characters per your second example). But keep in mind that there are lots of JVM implementations and they are only required to adhere to the JVM specification, not any conventions outside of that spec.

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

If you absolutely must ensure that no println calls will intersperse as you describe then you must enforce mutual exclusion manually, for example:

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

当然,这个例子只是一个说明,不应被视为解决方案";还有许多其他因素需要考虑.例如,上面的 safePrintln(...) 方法只有在 all 代码使用该方法并且没有任何东西调用 System.out.println(...) 直接.

Of course, this example is only an illustration and should not be taken as a "solution"; there are many other factors to consider. For example, the safePrintln(...) method above is only safe if all code uses that method and nothing calls System.out.println(...) directly.

这篇关于System.out.println 的多线程输出是否交错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆