0

In the code below how can I make number printer in black and red in order we expect, like below:

  • 1 (black)
    1 (red)
    2 (black)
    2 (red)

as opposed to what it actually does(some random order depending on whether the err or out streams are available):

  • 1 (black)
    2 (black)
    1 (red)
    2 (red)

code:

    package threads;

    public class CThread implements Runnable

{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
        outt(i);
        err(i);
        }

    }

    synchronized public void outt(int i){
        System.out.println(i);
    }
    synchronized public void err(int i){
        System.err.println(i);
    }

    public static void main(String [] org){
        Thread th = new Thread(new CThread());
        th.start();
    }


}
C graphics
  • 7,308
  • 19
  • 83
  • 134
  • Are you running this in an IDE or in a terminal/console? – azz Nov 08 '13 at 02:31
  • @DerFlatulator in IDE – C graphics Nov 08 '13 at 02:33
  • Ah, I was going to suggest using [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code) – azz Nov 08 '13 at 02:34
  • Comment for future answerers: This is not a buffering issue that can be solved by flushing. – Jeff Bowman Nov 08 '13 at 02:51
  • @JeffBowman please if you cannot answer the question leave it open so others can answer it. We know you posted your wrong answer and deleted it – C graphics Nov 08 '13 at 02:58
  • 1
    The question isn't answered in the other question, either. The accepted solution is incorrect. – azz Nov 08 '13 at 03:01
  • @Cgraphics I gave an unhelpful answer, before I tried it (and it failed) in my own IDE, and TBH I deleted it so you'd be more likely to get a better one—sometimes 0-answer questions get more attention. Then I got curious about the right answer, found an identical question, and linked it for SO's sake. My hunch is actually that Eclipse's console doesn't synchronize its stdout/stderr read operations, so you may be out of luck; in any case I hope that both your problem and the linked one are solved better, and the question only gets closed if the others agree they should be combined. Cheers! – Jeff Bowman Nov 08 '13 at 03:06
  • I'm digging around for a way to check the amount of bytes in an unflushed writer, if that information was available you could write a `while (!stderr.empty()) wait();`. Or something to that effect. – azz Nov 08 '13 at 03:37

2 Answers2

2

Even if you try to synchronize the writing of your Streams (System.out and System.err in that case), it does not prevent that the program which is watching those Streams (Eclipse in your case) is reading those streams in that order.

There is a lot of infrastructure between that (including the OS which can sort those IO operations in whatever order it wants).

For real world applications the answer to this kind of problem is to use a logging framework. With those you can write all messages of all levels to the same file (usually in a separate thread, in the order they where logged).

If you do not want to use a logging framework and want to rely on System.out / System.err, then you cannot reliably control on how this output is being read by 3rd party applications. The only thing you can do, is to synchronize the writing of those streams by synchronizing (and flushing) the IO operations with a common lock object. Be aware however that this technique then is a severe bottleneck to any multithreaded code.

Matthias
  • 3,582
  • 2
  • 30
  • 41
0

Create an ArrayList for output and error. Instead of System.out and System.err append to that list. Then decide when you like to print it and first print an empty the output list, the print and empty the error list. The has to be synchronized. Also: New output and error coming after the ignition of the printing will not be sorted in - of course - and this cannot be solved since the output to System.out and System.err is merged in the console first come first served. If you like to solve this you have to wait until the program finishes, then print all output and all error.

Christian Fries
  • 16,175
  • 10
  • 56
  • 67