System.out.println and System.err.println out of order

后端 未结 7 1183
灰色年华
灰色年华 2020-11-22 03:44

My System.out.println() and System.err.println() calls aren\'t being printed to the console in the order I make them.

public static         


        
7条回答
  •  我寻月下人不归
    2020-11-22 04:32

    The two println statements are handled by two different threads. The output again depends on what environment you are running the code in. For eg, I executed the following code in IntelliJ and command-line 5 times each.

    public class Test {
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                System.out.print("OUT ");
                System.err.print("ERR ");
            }
        }
    }
    

    This resulting in the following output:
    Commandline

    OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR
    OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR
    OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR
    OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR
    OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR OUT ERR
    

    IntelliJ:

    ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT 
    OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR
    ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT 
    ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT
    OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR 
    

    I guess different environments handles the buffers differently.
    One way to see that these streams are infact handled by different threads is to add a sleep statement in the loop. You can try varying the value that you set for the sleep and see that these are infact handled by different threads.

    public class Test {
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                System.out.print("OUT ");
                System.err.print("ERR ");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    The output in this case turned out to be

    OUT ERR ERR OUT ERR OUT OUT ERR OUT ERR ERR OUT OUT ERR ERR OUT OUT ERR OUT ERR
    OUT ERR ERR OUT ERR OUT OUT ERR OUT ERR ERR OUT OUT ERR ERR OUT OUT ERR OUT ERR
    ERR OUT ERR OUT OUT ERR ERR OUT OUT ERR ERR OUT OUT ERR OUT ERR ERR OUT ERR OUT 
    ERR OUT OUT ERR ERR OUT OUT ERR ERR OUT ERR OUT OUT ERR ERR OUT ERR OUT OUT ERR
    OUT ERR OUT ERR ERR OUT OUT ERR ERR OUT OUT ERR ERR OUT ERR OUT OUT ERR OUT ERR 
    

    One way to force it to print it in the same order would be use the .flush(), which worked for me. But itseems that not everyone is getting the right results with it.

    The two streams handled by 2 two different threads is probably the reason why we sometimes see the ERROR message printed by some libraries that we use, getting printed before some print statements that we were supposed to see according to the order of execution.

提交回复
热议问题