• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

join() method in Thread doesn't work as expected

 
Sandra Bachan
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Couldn't find an example in Sierra/Bates that uses join(), so I created my own (based on code from other parts of Sierra/Bates)

The intent of my code is for main thread to execute THEN the thread with nr job. However, the thread with nr job executes, then main:




Below is the output:

Run by Thread-0, x is 1
Run by Thread-0, x is 2
Run by Thread-0, x is 3
Run by Thread-0, x is 4
Run by Thread-0, x is 5
Run by main, x is 1
Run by main, x is 2
Run by main, x is 3
Run by main, x is 4
Run by main, x is 5



I was expecting main to execute first. Please clarify.
 
Ankit Garg
Sheriff
Posts: 9519
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are understanding the meaning of join method opposite. When A method calls b.join() it means that A will resume execution after thread b completes...
 
Arjun Srivastava
Ranch Hand
Posts: 432
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sandra Bachan wrote:
I was expecting main to execute first. Please clarify.

you have already started thread t before calling
if you want main thread to complete first and then thread t invokes
use
statement after t.join(); statement not before.
 
Sandra Bachan
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm trying to rearrange code so I can analyze the difference if I use join() vs not using join(). However, I get the same output regardless:




Output is always the same, whether I include t2.join() or not:

Run by t1, x is 1
Run by t2, x is 1
Run by t1, x is 2
Run by t2, x is 2
Run by t1, x is 3
Run by t2, x is 3
Run by t1, x is 4
Run by t2, x is 4
Run by t1, x is 5
Run by t2, x is 5


I would think that the output would be t1, followed by execution of all t2, then t1 resumes.

 
Arjun Srivastava
Ranch Hand
Posts: 432
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sandra Bachan wrote:
Output is always the same, whether I include t2.join() or not.

if you are not using

output can not be determined, as nothing is guaranteed in this case,if you are not using join() mehtod.
JVM can invoke any thread t1 or t2 ,nobody knows,depends upon the thread scheduler of your OS.
every time whether you will get same or different output,no one knows, it cannot be determined which thread will invoked first.
 
Sandra Bachan
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way, I am running my code on Ubuntu 9.04 which is on a virtual machine on Mac OS. However, when I run the following code on another machine that is Ubuntu 10.04 which is on a virtual machine on Ubuntu 9.04, I do notice slight difference.

Please note the modified code:



The abridged output:

Run by t1, x is 1
Run by t2, x is 1
Run by t1, x is 2
Run by t2, x is 2
Run by t1, x is 3
Run by t2, x is 3
Run by t1, x is 4
Run by t2, x is 4
Run by t1, x is 5
Run by t2, x is 5
Run by t2, x is 6

Run by t1, x is 6
...
Run by t1, x is 48
Run by t2, x is 48
Run by t1, x is 49
Run by t2, x is 49
Run by t1, x is 50
Run by t2, x is 50



It seems that t2 executes before t1, but at the very end t2 is the last to execute.

I I remove t2.join(), I get the following abridged output

Run by t1, x is 1
Run by t2, x is 1
Run by t1, x is 2
Run by t2, x is 2
Run by t2, x is 3

Run by t1, x is 3
Run by t1, x is 4

Run by t2, x is 4
Run by t2, x is 5

Run by t1, x is 5
Run by t2, x is 6
Run by t1, x is 6
...
Run by t2, x is 48
Run by t1, x is 48
Run by t2, x is 49
Run by t1, x is 49
Run by t2, x is 50
Run by t1, x is 50



I still don't have a firm grasp of this. Can you refer to any code that explains join() method.
 
Arjun Srivastava
Ranch Hand
Posts: 432
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
modify your code at line25

also use
before t1.join();
try this,and see the output.
 
Sandra Bachan
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Arjun Srivastava wrote:modify your code at line25

also use
before t1.join();
try this,and see the output.


@ Arjun: I did as you advised; below is the modified code:



However, t1 executes and then t2 executes.

If I comment out the t1.join() method, then t1 and t2 are interleaved.

Please tell me if I understand correctly: When we say t1.join(), it gives t1 priority over t2 such that t2 must wait for t1 to finish execution before t2 begins?
 
Arjun Srivastava
Ranch Hand
Posts: 432
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sandra Bachan wrote:
If I comment out the t1.join() method, then t1 and t2 are interleaved.
Please tell me if I understand correctly: When we say t1.join(), it gives t1 priority over t2 such that t2 must wait for t1 to finish execution before t2 begins?


this statement simply means that t2 will join to the end of t1 or you can say wait until t1 is done.
yeah you got it right.
 
Abimaran Kugathasan
Ranch Hand
Posts: 2066
Clojure IntelliJ IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is no point of calling join() on threads, which haven't started yet. The implementation is to "wait until the thread is no longer alive". If the thread is running, obviously, it means to wait til the thread is finished.

But since it only uses the alive flag to determine that it is finished, calling join() on a thread object that hasn't been started, will return immediately... as threads that haven't been started are not alive.

The calling thread waits until the thread finish it's job!
 
Sandra Bachan
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was studying this some more, and I changed the code such that t1 and t2 starts, then t1.join() is called. This is different from my previous code where t1 starts, t1.join() is called and then t2 starts.

The output I expected was the execution of all t1's followed by all t2's. However, t1 and t2 is interleaved. Please explain what is going on.


New code:



 
Hauke Ingmar Schmidt
Rancher
Posts: 436
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have three threads running: The main thread, t1 and t2.

You are calling t.join() from within the main thread so the main thread joins t1. The behaviour of t1 and t2 can't be predicted, but "interleaved" execution is fine.

If you want a thread to join another thread then you have to call join from inside the first thread.
 
Sandra Bachan
Ranch Hand
Posts: 434
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hauke Ingmar Schmidt wrote:You have three threads running: The main thread, t1 and t2.

You are calling t.join() from within the main thread so the main thread joins t1. The behaviour of t1 and t2 can't be predicted, but "interleaved" execution is fine.

If you want a thread to join another thread then you have to call join from inside the first thread.


After reading this and looking at the code again, it now makes sense!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic