6

System.out returns the "standard" output stream - a PrintStream. The javadoc of PrintStream tells me nothing about thread safety but looking at the source of the OpenJDK and the OracleJDK tells me that println is synchronized.

/**
 * Prints a String and then terminate the line.  This method behaves as
 * though it invokes <code>{@link #print(String)}</code> and then
 * <code>{@link #println()}</code>.
 *
 * @param x  The <code>String</code> to be printed.
 */
public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

That fits pretty well to my experiences: Calling System.out.println() never created 'mixed' output when calling from different threads.

So my question(s):

  1. Can I rely on this behavior (using different JVMs)?
  2. Is there some documentation that I missed which describes this behavior?
Iamat8
  • 3,888
  • 9
  • 25
  • 35
TobiSH
  • 2,833
  • 3
  • 23
  • 33

1 Answers1

6

Since the documentation of PrintStream, its superclass FilterStream, and its superclass OutputStream all fail to say anything about thread safety or synchronization, in theory you cannot rely on it, it's not part of the contract.

I think it would be surprising if someone produced a PrintStream class that didn't do what Oracle's does in this regard, but I've been surprised before.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    This! Unless it's clearly documented, it's open to interpretation. – paxdiablo Oct 01 '15 at 06:21
  • Having a `PrintStream` that isn’t thread safe would be more than just surprising, it would also create an unsolvable problem. To make it thread safe, you had to guard *every* access to it, but unfortunately, `System.out` is a globally visible resource and a lot of code accessing it is outside your control. We’re not only talking about 3rd party libraries but also logging code inside the JRE itself. – Holger Oct 01 '15 at 15:58
  • 1
    @Holger: You're assuming `System.out` is supposed to and/or claims to serialize output from multiple threads. I'm not aware of that claim being made anywhere. If a logging library is relying on output through `System.out` across multiple threads not being intermixed, well, they're relying on something they shouldn't be relying on. (Perhaps they *ought* to be able to rely on it, but the guarantee isn't there.) – T.J. Crowder Oct 01 '15 at 16:13
  • @T.J. Crowder: I’m not assuming that `System.out` is thread safe, I’m saying that if it isn’t, it is *impossible* to make it thread safe, as every attempt to do so implies relying on a particular behavior of *every* other code that accesses `System.out`, including the already existing log handler, provided by the JRE, that prints to the console. This handler *might* serialize logging, but as long as you don’t know, how it’s done, you can’t ensure compatibility with it. Recall, thread safety requires synchronizing on the *same* object or acquiring the *same* lock in *all* cases. – Holger Oct 01 '15 at 16:29
  • @Holger: *"I’m not assuming that System.out is thread safe, I’m saying that if it isn’t, it is impossible to make it thread safe..."* Absolutely. I understood that. I misunderstood the rest of your comment, I think. :-) I read it with an implied "...therefore you can assume it is synchronized." which absolutely is not present in your text. Sorry about that. – T.J. Crowder Oct 01 '15 at 16:34