0

Or do I need a lock to print synchronous output to the screen?

e.g.

//Main
public static void main(String[] args) {
   MyThread myThread1 = new MyThread();
   MyThread myThread2 = new MyThread();

   Thread thread1 = new Thread(myThread1);
   Thread thread2 = new Thread(myThread2);

   thread1.start();
   thread2.start();
}

//Custom thread 
public class MyThread() {
   public void run() {
      System.out.println("Is this method a shared resource that needs to be locked?");
   }
}

Will the above be susceptible to race conditions? Or is System.out.println() implemented with synchronization?

cbrad
  • 163
  • 1
  • 15
  • 1
    Define "race condition". At minimum, there's no guarantee which thread will get to print its message first. – Oliver Charlesworth Sep 27 '14 at 20:19
  • I'm not entirely sure what you're asking - are you afraid that the message stream would become interleaved with both outputs? – Makoto Sep 27 '14 at 20:19
  • 2
    Maybe this will answer your quesiton http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/io/PrintStream.java?av=f#804 – Pshemo Sep 27 '14 at 20:21
  • 5
    Pshemo's point is that `println(Object)` is synchronized, so a single string will be "atomic", though successive lines may be interleaved between threads. – Hot Licks Sep 27 '14 at 20:24
  • @OliverCharlesworth, by race condition I meant having a print statement being preempted before printing the entire String, and having it "concatenated" with some other threads output. – cbrad Sep 27 '14 at 21:21
  • Basically what @Makoto was alluding to. – cbrad Sep 27 '14 at 21:23
  • @Hot Licks, yep that is the desired functionality – cbrad Sep 27 '14 at 21:23
  • Is there a simple way to turn an existing comment into an answer? – cbrad Sep 27 '14 at 21:27

3 Answers3

1

Makoto's answer is all true, but it is not the whole truth. The documentation for java.io.PrintStream says nothing about threads. The behavior of overlapped calls to print(...) methods on the same stream oficially is undefined.

Can you tolerate undefined behavior in your code? Often times, with adequate testing, the answer is yes. But if a bug in your code could threaten people's lives, threaten the finances of some mega-corporation, threaten the success of a historic space mission, etc. then relying on undefined behavior could be a career-limiting move.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • I appreciate your input @james large. This is an important point. I'm sure if the documentation does not specify having any java.io.PrintStream syncrhonized, certain implementations may not bother locking it. The specific code that prompted this question for me fortunately does not have anywhere near the consequences that you described but in the future double checking the documentation on the implementation you're using would be wise. – cbrad Sep 28 '14 at 23:39
0

Since the implementation of println is synchronized on that instance, there's virtually no chance that the stream will self-corrupt.

If you have different threads printing different things, however, you may see non-deterministic behavior in that the order you perceive things to be printed isn't the order in which they actually are. That's a separate concern to the actual corruption of the stream you're writing to.

Makoto
  • 104,088
  • 27
  • 192
  • 230
  • 2
    Sorry println is not threadsafe. And there are multiple threads writing into System.out in this example. http://stackoverflow.com/questions/9459657/synchronization-and-system-out-println – fodon Sep 27 '14 at 21:35
  • @fodon: Erm...did you read a bit further into that answer? The accepted answer actually corroborates what's been discussed here. Not just that, but if one inspects the source to `println` which is linked in this answer, the behavior described in the actual source code is *the exact same* as being suggested in the answer. – Makoto Sep 27 '14 at 21:38
  • Further, multiple threads writing to `System.out` is only a thread safety concern if the stream being written to had its output suddenly munged with the output of another stream. That simply does not occur since there is synchronization around the printing. You'll see different outputs at different times; that'd be non-deterministic behavior, not a lack of thread safety. – Makoto Sep 27 '14 at 21:42
  • 2
    All I'm saying is that you can't assume that this is the case with all JVMs ... because the documentation doesn't mention that this method is synchronized. – fodon Sep 27 '14 at 21:45
  • That's fair. But, one could assume Oracle's JVM is used in the lion's share of projects nowadays. It may be undocumented, but if the code is actually doing something to make it thread safe, it's incorrect to make a blanket statement saying that it isn't. – Makoto Sep 27 '14 at 21:47
  • 2
    All I said is that there is a threat that something strange gets written out. – fodon Sep 27 '14 at 21:51
  • I'm getting the behavior described by the answer here using Java version 6.20 if that helps... – cbrad Sep 27 '14 at 21:51
  • @Makoto, It all depends... Do you want to write a demo that works today in a controlled environment? Or do you want to write reliable software that runs in an environment governed by contract? If it's to be a demo, then you can safely base your decisions on how the other party's code happens to perform at the present moment. If it's to be reliable software though, you're better of trusting the documentation, and negotiating with the other party if their software ever fails to live up to what its documentation promises. – Solomon Slow Sep 28 '14 at 12:18
-3

Yes, there is a threat that you'll get into race conditions ... partial message will be written out by one thread.

The solution is to use one of the loggers like log4j. Check this tutorial out.

fodon
  • 4,565
  • 12
  • 44
  • 58