• Post Reply Bookmark Topic Watch Topic
  • New Topic

Threads -- Strange Outputs  RSS feed

 
rs ravindra
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I came across a Java piece of code (Threads) recently as one of my colleagues was preparing for OCPJP. For experimenting with Threads, she tweaked the code a little so as to produce the below code :-



Nothing so strange about the code. But I did get some strange outputs when the above code was run, which I couldn't explain to myself. Below are all the results that I got while running the above code over several times :-

0 1 2 0 1 2
0 0 1 2
0 1 2 0
0 1 2 1 1 2
0 1 1 1 2
0 0 2 1
0 1 2 3
0 1 1 0 2

Can anyone please decipher and explain to me how each of these outputs could have been arrived at..?

Kindly excuse me if I haven't followed any of the forum rules as I am posting a query for the first time in this forum.

Thanks
 
Rohan Deshmkh
Ranch Hand
Posts: 127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When i ran the code it gave output as:
0 1 2 0 1 2
which is expected.Don't know how you are getting different output.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rohan Deshmkh wrote:When i ran the code it gave output as:
0 1 2 0 1 2
which is expected.


That's not the expected output. It's one of several possible outputs.
 
Rohan Deshmkh
Ranch Hand
Posts: 127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:
Rohan Deshmkh wrote:When i ran the code it gave output as:
0 1 2 0 1 2
which is expected.


That's not the expected output. It's one of several possible outputs.

yes we cannot predit output when we are playing with threads.I should have written it correctly.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
rs ravindra wrote:I came across a Java piece of code (Threads) recently as one of my colleagues was preparing for OCPJP. For experimenting with Threads, she tweaked the code a little so as to produce the below code :-



First, don't extend Thread. Implement Runnable instead. You're not creating a specialized type of Thread, you're just defining a task to run in a thread. It's a design error in Java that extending Thread that way is even an option. And if you're going to go ahead and extend Thread anyway, you don't need new Thread(Trans), because a Trans is already a Thread. You can just call start() on your Trans object.

Not that any of that has anything to do with your question. Just general advice.

As for your question...

The whole point of threads is that they can run independently of each other. Maybe simultaneously, on 2 different CPUs, maybe taking turns executing several instructions each, maybe one executes start to finish before the other one starts. We don't know and we don't care how they'll be scheduled. And if we do need to exert some control over that--one thread stopping at some point until another thread has complete a certain task--we use things like synchronized, wait(), notifyAll(), and java.util.concurrent.*;

That, combined with the fact that those threads are sharing the same loop variable (something you'd probably never do in real life) AND the fact that the shared variable is not volatile and is not accessed inside synchronized blocks (giving each thread the ability to use it's own local cached copy sometimes and the master copy other times), means the output will be unpredictable, and can vary from run to run.

For example, here are how a couple of the outputs could theorertically come about. There are other possibilities too.



0 1 2 0 1 2

T1 and T2 each use their own cached copy of counter. After both threads start and read counter, T1 executes to completion, then T2 executes to completion.

0 0 1 2

Both threads start up and read counter. T2 executes its first pass of the loop. T1 then executes to completion and writes the last value of counter out to the main copy. T2 goes for its next pass of the loop, reads counter from main mem, finds it's already >=3, and does not enter the loop any more.
 
rs ravindra
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jeff for analyzing and providing explanation for the above code.

Jeff Verdegan wrote:First, don't extend Thread. Implement Runnable instead. You're not creating a specialized type of Thread, you're just defining a task to run in a thread. It's a design error in Java that extending Thread that way is even an option. And if you're going to go ahead and extend Thread anyway, you don't need new Thread(Trans), because a Trans is already a Thread. You can just call start() on your Trans object.


As mentioned in my query, actually this wasn't a piece of code written by me, but I came across this snippet in some mock test for OCPJP. I myself wouldn't have written a Threading code this way.. !!

Jeff Verdegan wrote:
That, combined with the fact that those threads are sharing the same loop variable (something you'd probably never do in real life) AND the fact that the shared variable is not volatile and is not accessed inside synchronized blocks (giving each thread the ability to use it's own local cached copy sometimes and the master copy other times), means the output will be unpredictable, and can vary from run to run.

For example, here are how a couple of the outputs could theorertically come about. There are other possibilities too.



0 1 2 0 1 2

T1 and T2 each use their own cached copy of counter. After both threads start and read counter, T1 executes to completion, then T2 executes to completion.

0 0 1 2

Both threads start up and read counter. T2 executes its first pass of the loop. T1 then executes to completion and writes the last value of counter out to the main copy. T2 goes for its next pass of the loop, reads counter from main mem, finds it's already >=3, and does not enter the loop any more.


This seems to be an adequate explanation for my query. I wasn't aware about the concept of 'cached copy' as you've mentioned above. Probably that explains some of the outputs to me.

Again, Thanks for the effort.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!