1

I have a problem with understanding this code , My question is why the two threads does not interfere with each other during executing the statements in run method ?

I mean that always a thead do all statements then come second thread to do statements.

it is impossible that first thread do portion of statements then second thread do portion of statements then first thread continue its task .............

note : I know that the two threads uses different OutputStream object

Thread code here

class Printer extends Thread
{
   private String ThreadName;

   public Printer(String name)
   {
       this.ThreadName=name;
   }

   public void run()
   {
       PrintStream out=new PrintStream(System.out);

       out.println(this.ThreadName+" : a");
       out.println(this.ThreadName+" : b");
       out.println(this.ThreadName+" : c");
       out.println(this.ThreadName+" : d");
       out.println(this.ThreadName+" : e");
       out.println(this.ThreadName+" : f");
       out.println(this.ThreadName+" : g");
       out.println(this.ThreadName+" : h");
       out.println(this.ThreadName+" : i");
       out.println(this.ThreadName+" : j");
       out.println(this.ThreadName+" : k");    
   }
}

Entry Code:

class Main 
{
    public static void main(String[] args)
    {
        Thread t1 = new Printer("thread 1");
        Thread t2 = new Printer("thread 2");

        t1.start();
        t2.start();
    }
}

try to replace System.out with out and compare the results then you will know exactly what am I asking for

user1841718
  • 187
  • 1
  • 4
  • 15
  • Please clean up your code sample. – millimoose Feb 11 '13 at 17:01
  • Have you researched anything so far? What did you find? – Aaron Kurtzhals Feb 11 '13 at 17:04
  • the fact that they do not interfere when you run them does not imply that they do not interfere in general (e.g. run on another computer, under different circumstances etc.). When I run the code, the output of the first thread is typically 'paused' just before the newline when the output of the other thread is printed. And when repeatedly running the program, I get a different output each time. – Andre Holzner Feb 11 '13 at 17:06
  • 2
    My best guess at answer is "because that's how the scheduler chose to run them". It might also have something to do with the fact they're all trying to block the same resource (`System.out`), which I think might be synchronized. – millimoose Feb 11 '13 at 17:07
  • change your run to `for (int i = 0; i < 1000; i++) System.out.println(i);` and you should get the behaviour you expect (if not increase it to 100000). Your run probably completes too fast and the second thread has not had time to start yet. – assylias Feb 11 '13 at 17:10
  • see http://stackoverflow.com/a/9459886/288875 : there is no guarantee that `System.out` is synchronized, but as @millimoose points out, it **may** be, depending on the JVM implementation (but that's not something you can rely on). – Andre Holzner Feb 11 '13 at 17:12
  • @AndreHolzner At this point, I'd say that's more theory than practice, but it is a fair point. – pickypg Feb 11 '13 at 17:19
  • try to replace `System.out` with `out` and compare the results then you will know exactly what am I asking for – user1841718 Feb 11 '13 at 17:23

2 Answers2

1

A couple of things before the explanation:

It's unnecessary to extend Thread, and it is easier to just implement Runnable, which provides the run method that you are implementing. At this point, you can give the Runnable to a Thread or, more usefully, an Executor (very useful for multithreading in Java).

Also, wrapping System.out in a PrintStream is redundant, as System.out is already a PrintStream itself.

Finally, your code is not sharing anything, which is why they do not interfere with each other. All each one does is print out their name and a unique letter so you can find it. System.out is thread safe in the Sun implementation (as noted by Andre, that's technically not required by JVM implementations), so you will not be able to break output up, but that does not stop you from potentially interweaving output.

For example, if you run this enough, then you could easily see:

thread 1 a
thread 2 a
thread 1 b
thread 2 b

However, I suspect that you are seeing:

thread 1 a
    .
    .
    .
thread 1 k
thread 2 a
    .
    .
    .
thread 2 k

This is not because something is broken, rather it's because the thread executes so quick that it just happens that way. Since you are learning, it would be good to add in some Thread.sleep calls between output with random delays so that you can hopefully observe the interweaving.

pickypg
  • 22,034
  • 5
  • 72
  • 84
  • do you main if a thread has a recource then it will do all operation related with that resource ? thanks for your answer – user1841718 Feb 11 '13 at 17:44
  • Because `Thread`s do not talk to each other by default, the idea of consuming a resource does not exist to them. What that means is that, if you give the same resource to two different `Thread`s, then one `Thread` may potentially use more of it (whatever that means with respect to the resource) than the other, which conversely means the other one may use less of it. If two `Thread`s use separate resources, then they will not have any effect on each other. `Thread`s are brainless, and they only serve as a mechanism to potentially work in parallel; communication is up to the implementation. – pickypg Feb 11 '13 at 17:49
  • actually this answer is exaclty what am I search for , thanks – user1841718 Feb 11 '13 at 18:07
0

In System.out.println() out is also reference of PrintStream so you are calling the same println() in both ways.

But you are getting different output. Although println function has synchronized implementation.

public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

Now think, out in System.out.println is static while PrintStream out is not.

PrintStream out=new PrintStream(System.out);

In above statement new reference of out is non static.

If the method is not static, then adding synchronized keyword will synchronize the instance of the class, not the Class object.

So to get your desired result make PrintStream out static