2

I knew that System.out is buffered. It will not print the output to terminal until it is explicitly flushed or program is terminated.

I wrote below program to test my understanding. I was thinking that output of my program would be printed when the program terminates because i am not explicitly flushing the stream. But the output is getting printed as soon as print is executed and then program goes into 5 second sleep.

Could anyone please suggest the reason.

class PrintandSleep {
   public static void main(String args[]) throws InterruptedException{
       System.out.print("xyz");
       Thread.sleep(5000);
   }
}
Community
  • 1
  • 1
pradeep
  • 69
  • 5
  • 4
    Surely you want to swap the two lines round? – hertzsprung Jun 18 '14 at 08:02
  • 4
    I'm really confused as to how this would be confusing. You're telling the program to print, then sleep. I fail to see why you would expect it to be the other way. Unless you're used to reading from bottom to top? – awksp Jun 18 '14 at 08:03
  • 3
    @user3580294 Since System.out is supposed to be line buffered, the OP would also assume that System.out.print() isn't printing anything (since there's no newline anywhere), at least not until the stream is closed, at program exit. – nos Jun 18 '14 at 08:05
  • 1
    @nos Ah, that makes sense. Didn't click until you said that. – awksp Jun 18 '14 at 08:10
  • 1
    @user3580294 I was expecting that buffer would be flushed and output will appear when program terminates,because System.out is buffered stream. – pradeep Jun 18 '14 at 08:12
  • possible duplicate of [Will Java's System.out.print() buffer forever until println()?](http://stackoverflow.com/questions/9402529/will-javas-system-out-print-buffer-forever-until-println) – Alexandre Santos Jun 18 '14 at 08:43

1 Answers1

2

The reason is that the writer is constructed with flag auto flush set to true.

public PrintStream(OutputStream out, boolean autoFlush, String encoding)

In such case when we invoke write(String) we invoke flush() as well.

The code from version 8:

java.io.PrintStream

 public void print(String s) {
        if (s == null) {
            s = "null";
        }
        write(s);
    }


private void write(String s) {
        try {
            synchronized (this) {
                ensureOpen();
                textOut.write(s);
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush && (s.indexOf('\n') >= 0))
                    out.flush();
            }
        }
        catch (InterruptedIOException x) {
            Thread.currentThread().interrupt();
        }
        catch (IOException x) {
            trouble = true;
        }
    }

Look in the code when you can not determine what is going on.

  • 1
    Interestingly, at least from a quick trip to the debugger the `autoFlush` flag actually doesn't matter in this case, as (at least on my computer) output is written to the console before the flag is checked. Not too sure what's going on. – awksp Jun 18 '14 at 08:18
  • Here we are invoking `print(String)`, not `write(String)`. The documentation doesn't say anything about `autoFlush` having an effect. – Joni Jun 18 '14 at 08:20
  • Additionally, the interesting thing is that both `System.err` **and** `System.out` are constructed with `autoFlush=true` (see http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/cf44386c8fe3/src/share/classes/java/lang/System.java) - does this not mean that outputs to System.err and System.out should always be in sync (which is not, as we know)? – Andreas Fester Jun 18 '14 at 08:21
  • @Joni, print is public, write is private. Calling print you call write. – Damian Leszczyński - Vash Jun 18 '14 at 08:23
  • In case it matters, output occurred for me at the call to `charOut.flushBuffer()`. Diving further resulted in a call to a `sun.something.something` class that I didn't have the source to. – awksp Jun 18 '14 at 08:25
  • @user3580294 ... which makes sense, since the code above shows that `out.flush()` is only called if `autoFlush` is `true` AND the string contains a newline (which it does not in the OPs code) – Andreas Fester Jun 18 '14 at 08:27
  • 1
    @Andreas Er, rewrite. I'm curious as to the distinction between the various output streams/writers then and when flushing one or the other would matter. From my inspection of the javadoc `text/charOut.flushBuffer()` just flushed some buffers without flushing the underlying byte stream, so I'm a bit curious as to what's going on... – awksp Jun 18 '14 at 08:28