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:

Community
  • 1
  • 1
C graphics
  • 7,308
  • 19
  • 83
  • 134
  • 5
    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)? – JB Nizet Feb 28 '13 at 23:01
  • 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." – KevinDTimm Feb 28 '13 at 23:02
  • 1
    Both streams are synchronized, but not on the same lock, so you should expect some interleaving... However, each stream, individually, will be ordered. – assylias Feb 28 '13 at 23:09
  • https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205 – Maarten Bodewes Feb 28 '13 at 23:09
  • @owlstead which basically says: by design. ;-) – assylias Feb 28 '13 at 23:11
  • @assylias 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 threads – Maarten Bodewes Feb 28 '13 at 23:12
  • @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. – Maarten Bodewes Feb 28 '13 at 23:32
  • Cgraphics @KevinDTimm says you are using Eclipse, but I cannot find that anywhere in your question. Could you indicate your runtime? – Maarten Bodewes Feb 28 '13 at 23:41
  • Yap! I am using Eclipse, what do you mean by runtime? – C graphics Mar 01 '13 at 00:25

3 Answers3

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.

Ankit
  • 6,772
  • 11
  • 48
  • 84
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);
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 7
    This would likely work, but you would loose the highlighting that Eclipse applies. – Maarten Bodewes Feb 28 '13 at 23:10
  • @owlstead Well this is the same as replacing the System.err.println("B"); with System.out.println("B"); – C graphics Feb 28 '13 at 23:17
  • @Cgraphics Yes, it is almost the same. It would be something like having 2 references to the same stream. – Eng.Fouad Feb 28 '13 at 23:19
  • 1
    @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... – Maarten Bodewes Feb 28 '13 at 23:19
0

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

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
Ahmet Karakaya
  • 9,899
  • 23
  • 86
  • 141
  • 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. – Maarten Bodewes Feb 28 '13 at 23:25
  • you are right, I totally agree with you. That is why the order of A/B is possible. There can be any order too. – Ahmet Karakaya Feb 28 '13 at 23:28