猿问

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

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

而不是交替outerr..这是为什么?


烙印99
浏览 647回答 3
3回答

www说

它们是不同的溪流,在不同的时间被冲洗。如果你把System.out.flush();System.err.flush();在您的循环中,它将按预期工作。为了澄清,输出流被缓存,所以所有的写都进入这个内存缓冲区。经过一段时间的安静,他们实际上是写出来的。您给两个缓冲区写信,然后经过一段时间的不活动,它们都会被刷新(一个接一个)。

犯罪嫌疑人X

这是由jvm中的特性造成的,除非您进行了黑客攻击,例如马库斯A.工作并不是那么容易。这个.flush()在这种情况下可以工作,但其原因要复杂得多。这里发生了什么?当您用Java编程时,您没有直接告诉计算机要做什么,而是告诉JVM(Java虚拟机)您希望它做什么。它会做到这一点,但以更有效的方式。您的代码不是精确的详细说明,在这种情况下,您只需要像C和C+那样的编译器,JVM就会将您的代码作为一个规范列表,说明它应该优化什么,然后做什么。这就是这里发生的事..Java看到您正在将字符串推入两个不同的缓冲区流。最有效的方法是缓冲所有您希望流输出的字符串,然后输出它。这在当时只发生一个流,本质上是转换代码,执行如下操作(小心:伪码):for(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;5;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;out.add(); &nbsp;&nbsp;&nbsp;&nbsp;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的特性,以便重新安排和优化您的代码。*我无法验证您添加到的缓冲区是否总是先打印,但很可能会打印出来。
随时随地看视频慕课网APP

相关分类

Java
我要回答