Race between System.out and System.err in java [duplicate]
Asked Answered
A

3

19

Please consider this java code:

public class CMain {
    public static void main(String[] args){

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

    }
}

By a quick look at the code, some of us may think the output has to be the print of As and Bs alternatively. However is not! It is a random appearance of 10 A characters and 10 B ones. Something like this:

enter image description here

Why is that? and what is the solution for it so that the As and Bs gets displayed alternatively ( A B A B A B ...) Before I ask this question, I checked several other similar questions for solution and non worked for my case! I have brought some of them here:

Anglophobe answered 28/2, 2013 at 22:58 Comment(9)
Those are two different streams that happen to be merged into the same console. If you want everything at a single place and in a given order, why don't you use a single stream (out OR err)?Affer
I think the answer is in your second link "The problem is that it's the responsibility of the terminal emulator (in your case, Eclipse) to process the standard output and the standard error of your application. Without communicating with the terminal emulator, you can never be sure that out and err are displayed in the right order. Therefore, I would consider printing everything on err and redirect it to a file. You can still use out for clean user interaction."Clayborn
Both streams are synchronized, but not on the same lock, so you should expect some interleaving... However, each stream, individually, will be ordered.Inefficient
bugs.eclipse.org/bugs/show_bug.cgi?id=32205Balcer
@owlstead which basically says: by design. ;-)Inefficient
@Inefficient I've got the gut feeling that it can be fixed, as Eclipse should have enough control over the streams, but it's design is indeed not able to handle it, with 2 threadsBalcer
@DocMax No not really, that answer does not fix anything, these are println statements, and both streams should be auto-flushed. Actually, it is an incorrect answer even if it has +12. Interesting.Balcer
Cgraphics @Clayborn says you are using Eclipse, but I cannot find that anywhere in your question. Could you indicate your runtime?Balcer
Yap! I am using Eclipse, what do you mean by runtime?Anglophobe
L
12
Why does this happen?

This is because out and err are two different output streams. However, both of them print on console. So you do not see them as different streams. Moreover, when you do out.println(), it is not guaranteed that you will see the output on the console as soon as the statement gets executed. Instead, the strings are usually(depends on the system) stored in an output buffer (if you will) which is processed later by the system to put the output from the buffer onto the screen.

Solution :(

Although, as Eng.Fouad pointed out that you can use setOut(System.err) or setErr(System.out) to make them ordered, I would still not suggest doing that when you are actually putting this in an application (only use it for debugging purposes).

What the proposed solution does is that it will end up using only one stream for both the standard output and the standard error, which I do not think is a good thing to do.

Lophobranch answered 28/2, 2013 at 23:7 Comment(2)
I guess that depends on the system, Ankit...Balcer
@owlstead yes ( I am assuming you are talking about the buffering)Lophobranch
N
6

They are different OutputStreams. If you really need to guarantee the order of printing them, use:

System.setErr(System.out);

or

System.setOut(System.err);
Nelan answered 28/2, 2013 at 23:10 Comment(4)
This would likely work, but you would loose the highlighting that Eclipse applies.Balcer
@owlstead Well this is the same as replacing the System.err.println("B"); with System.out.println("B");Anglophobe
@Cgraphics Yes, it is almost the same. It would be something like having 2 references to the same stream.Nelan
@Cgraphics of course, but there is a difference between (temporarily) changing System.out or System.err to be able to debug correctly in Eclipse and altering each and every one of the System.out.println statements...Balcer
Z
0

Since there are two separate streams, the output you are giving is possible.

Zeena answered 28/2, 2013 at 23:3 Comment(2)
Depends on the system, both System.out and System.err are auto flushed by default. It's eclipse that does not detect the order in which bytes or characters are written. They are necessarily in order as println() should only return after flushing the stream.Balcer
you are right, I totally agree with you. That is why the order of A/B is possible. There can be any order too.Zeena

© 2022 - 2024 — McMap. All rights reserved.