2012-03-29 108 views
3

任何人都可以告诉我为什么运行此循环后总是有这种奇怪的输出?这是一个线程问题还是什么?运行循环时奇怪的输出

for(int i=0;i<10;i++){ 
    System.out.println("out: "+i); 
    System.err.println("err: "+(i+1)); 
    } 

- >输出:

err: 1 
    out: 0 
    err: 2 
    err: 3 
    err: 4 
    out: 1 
    out: 2 
    out: 3 
    out: 4 
    err: 5 
    out: 5 
    err: 6 
    out: 6 
    err: 7 
    err: 8 
    out: 7 

    out: 8 
    err: 9 
    out: 9 
    err: 10 
    out: 10 

回答

11

您的终端正在运行您的应用程序,并且有两个文件描述符连接到它,一个用于stdout,一个用于stderr。然后它必须读取应用程序在这些文件描述符上输出的数据并将其呈现在屏幕上。不能保证终端应用程序(或者操作系统)如何实现这种交互。想象一下,终端实际上​​有两个线程并行地从stdout和stderr读取数据。这两个线程将从fds和屏幕上获取数据的顺序不能保证与您的应用输出时的顺序相一致。

+0

这很有趣。我最初因为我认为这是错误的而低估了。这是我的假设,Java是缓冲'System.out'和'System.err'没有缓冲。但是如果我从命令行运行一个类,我会看到''oeoeoeoeoeoeoeoeoe''完全交错。这意味着这是应用程序正在做一些不同的事情。迷人。谢谢@MK。 +1 – Gray 2012-03-29 22:50:14

+0

@Gray我认为你是正确的System.err没有缓冲,但我不认为这些是相互排斥的。我试图给出一个普遍的感觉,为什么这些会交错。另外我认为印刷\ n可能导致潮红?在这种情况下,stdout和stderr的行为将是相同的。 – 2012-03-30 02:41:12

+0

我的评论并不反对你。我完全同意。默认情况下,PrintStream在看到'\ n'时不会刷新。我不知道如何配置System.out和System.err。 – Gray 2012-03-30 13:15:47

3

标准输出和标准误差有单独的缓冲器。交错是正常的。在每次打印呼叫后尝试flushing输出流。