为了账号安全,请及时绑定邮箱和手机立即绑定

Java:System.out.println和System.err.println无序

Java:System.out.println和System.err.println无序

烙印99 2019-06-24 13:24:09
Java:System.out.println和System.err.println无序我的System.out.println()和System.err.println()呼叫没有按我的顺序打印到控制台。public static void main(String[] args) {     for (int i = 0; i < 5; i++) {         System.out.println("out");         System.err.println("err");     }}这就产生了:out out out out out err err err err err而不是交替out和err..这是为什么?
查看完整描述

3 回答

?
www说

TA贡献1775条经验 获得超8个赞

它们是不同的溪流,在不同的时间被冲洗。

如果你把

System.out.flush();System.err.flush();

在您的循环中,它将按预期工作。

为了澄清,输出流被缓存,所以所有的写都进入这个内存缓冲区。经过一段时间的安静,他们实际上是写出来的。

您给两个缓冲区写信,然后经过一段时间的不活动,它们都会被刷新(一个接一个)。


查看完整回答
反对 回复 2019-06-24
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

这是由jvm中的特性造成的,除非您进行了黑客攻击,例如马库斯A.工作并不是那么容易。这个.flush()在这种情况下可以工作,但其原因要复杂得多。

这里发生了什么?

当您用Java编程时,您没有直接告诉计算机要做什么,而是告诉JVM(Java虚拟机)您希望它做什么。它会做到这一点,但以更有效的方式。您的代码不是精确的详细说明,在这种情况下,您只需要像C和C+那样的编译器,JVM就会将您的代码作为一个规范列表,说明它应该优化什么,然后做什么。这就是这里发生的事..Java看到您正在将字符串推入两个不同的缓冲区流。最有效的方法是缓冲所有您希望流输出的字符串,然后输出它。这在当时只发生一个流,本质上是转换代码,执行如下操作(小心:伪码):

for(int i = 0; i < 5; i++) {
    out.add();
    err.add();}out.flush();err.flush();

因为这更有效率,这就是JVM所要做的事情。添加.flush()在循环中,将向JVM发出信号,表示每个循环都需要进行刷新,这不能用上面的方法进行改进。但是,如果您为了解释这是如何工作的,那么JVM将重新排序您的代码,以便最后完成打印,因为这样做效率更高。

System.out.println("out");System.out.flush();System.err.println("err");System.err.flush();System.out.println("out");System.out.flush();
System.err.println("err");System.err.flush();

此代码将始终被重新组织如下所示:

System.out.println("out");*System.err.println("err");*System.out.println("out");*System.err.println("err");*System.out.flush();
System.err.flush();

因为缓冲许多缓冲区只是为了在之后立即刷新它们,而不是缓冲所有要缓冲的代码,然后同时刷新它们。

如何解决

这就是代码设计和体系结构可能发挥作用的地方;你几乎解决不了这个问题。要解决这一问题,您必须使缓冲打印/刷新、缓冲区打印/刷新比缓冲区全部刷新更高效。这很可能会吸引你进入糟糕的设计。如果重要的是如何有序地输出它,我建议您尝试另一种方法。用.循环.flush()是破解它的一种方法,但您仍然在侵入JVM的特性,以便重新安排和优化您的代码。

*我无法验证您添加到的缓冲区是否总是先打印,但很可能会打印出来。


查看完整回答
反对 回复 2019-06-24
  • 3 回答
  • 0 关注
  • 627 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号