• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

join() method; guarenteed behaviour

 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
From K&B book.

When one thread calls the join() method of another thread, the currently
running thread will wait until the thread it joins with has completed.


Here is a sample program, I coded to understand join() method.
Here t.join() is invoked from the main method. The 'main' Thread will wait till thread 't' has completed.
Here do I modify the code, if I want the threads 't','t2','t3' be executed one followed by the other irrespective of 'main' Thread. Output:0 0 0 before join
1 1 1 2 2 2 end of main
 
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not sure if you can!
You can synch the run method such that it won't get interrupted but that doesn't guarantee the order of threads started, you specified t then t2 then t3.
Remember that the output you gave is not guaranteed - try running it several times...
[ June 05, 2008: Message edited by: Frank Zito ]
 
Ram Manoj
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Frank,

I think there is confusion here.

What I want is 't2' thread join 't' and 't3' thread join 't2'.

So for this how do i modify my code!
 
Karl Prenton
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
does this help (modifies main method though) ?

 
Ranch Hand
Posts: 88
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi manoj,

I hope i understood your requirement.
Please find two programs below.

Program 1 :- is like your requirement

program 2:- to execute threads one by one . I think this is not a good approach.

program 1:-


class Test12 extends Thread
{
Thread threadObj = null;
public Test12() {}
public Test12(Thread thread)
{
this.threadObj = thread;
}
public static void main(String...strings)
{
Test12 t = new Test12();
Test12 t2 = new Test12(t);
Test12 t3 = new Test12(t2);
t.start();
t2.start();
t3.start();
System.out.println("before join");
try
{
t.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("end of main");
}
public void run()
{
System.out.println("Run Method of " + Thread.currentThread().getName());
try
{
if(threadObj != null)
{
threadObj.join();
}
for(int i=0;i<3;i++)
{
System.out.print(i+" ");
sleep(100);
}
System.out.println("End of Thread " + Thread.currentThread().getName());
}
catch(InterruptedException e)
{
System.out.println("Interrupted Exception");
}
}
}

program 2:-



class MainJoin
{
public static void main(String...strings) throws Exception
{
Join j1 = new Join();
Join j2 = new Join();
Join j3 = new Join();
j1.setName("Join Thread 1");
j2.setName("Join Thread 2");
j3.setName("Join Thread 3");
System.out.println("Before starting the thread J1");
j1.start();
System.out.println("Before joining the J1 Thread");
j1.join();
System.out.println("Before starting the thread J2");
j2.start();
System.out.println("Before joining the J2 Thread");
j2.join();
System.out.println("Before starting the thread J2");
j3.start();
System.out.println("Before joining the J3 Thread");
j3.join();
System.out.println("End of the main thread");
}
}

class Join extends Thread
{
public void run()
{
System.out.println("Start of the thread " + Thread.currentThread().getName());
for(int i = 0; i < 10; i++)
{
System.out.println(" I value is " + i);
}
System.out.println("End of the Thread : " + Thread.currentThread().getName());
}
}

Can any one tell me is the second program is a good approach?
If not how to write it another way?

Rami.
 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I really don't understand how join() works. If join() comes after you have started the threads (which are now for arguments sake are running), when the main hits the join() call for that thread... its a little bit too late as they threads have already started.

As an example, here some code I wrote, wanting the output to be along the lines of a thread starts, that thread finishes before another one starts and finishes and then the last one starts and finishes. This is what I understand the join() method to do.



What I find is that join() is being called AFTER the threads have all completed!

Actual Output:
one started
three started
two started
one finished
three finished
two finished

Desired Output:
one started
one finished
two started
two finished
three started
three finished


I am 100% sure I am missing some fundamental rule and would appreciate your help.
[ June 06, 2008: Message edited by: Mustafa Musaji ]
 
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mustafa,

to get the output your requiring, I think you need to add the "synchronize" keyword to your "run" method. This I think forces only one thread to access the method at a time. I tried it with your example and it worked for me, although I had to increase your variables quite alot to slow my machine down!!

I hope this helps.

Robert.
 
Mustafa Musaji
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Robert,

I agree with you, using synchronize does work, but then there would be no need for the join() method as each thread would access the run method seperately anyway right?

I guess what I am trying to say is I don't quite understand how the join() method is used correctly. When I see it in a mock I just seem to get confused as to what the code will do.

Should I just hope I don't get too many Thread questions in my SCJP Exam!!!
 
robert stannard
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mustafa,

I may have given you a "bum steer" in my previous post. I think you need to add a "synchronized" block to the code and lock on an external Object like "System.out" to lock that bit of code from other Threads. I made this small change to your code,


which then gives me the Ouput,
One Started
One Finished
Three Started
Three Finished
Two Started
Two Finished

I dont think its possible to tell the scheduler which thread to run next - thats why you have thread "Three" running before thread "Two" - but as you can see from the output, once a thread is in your "Run" method, no other thread can access the code until its finished.

I hope this helps.
 
robert stannard
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think the problem with your Join is that you are joining to the Main thread and not joining one thread to another, so what happens is that the Main thread runs and completes and then the other threads run on after the other in not particular order.

I also struggle with Thread questions and am hoping that I dont have too many difficult ones !
 
Mustafa Musaji
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Forgot to say that to use synchronize you would have also have create one "GoingRunning" object and three Thread objects using the same "GoingRunning". Synchronize would only work on the same object.

Basically it would mean I could not create three different objects of GoingRunning and have them access the run() method one after the other using synchronize. I could use synchronized(GoingRunning.class)....

.... anyway, my point is I don't understand join()!!!
 
Mustafa Musaji
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by robert stannard:
I think the problem with your Join is that you are joining to the Main thread and not joining one thread to another, so what happens is that the Main thread runs and completes and then the other threads run on after the other in not particular order.

I also struggle with Thread questions and am hoping that I dont have too many difficult ones !



This sort of makes sense, but then where would I put the code to join the threads?
 
robert stannard
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think you can do that - not from within the Main() method anyway.

I think what I said before about the Join was actually the wrong way around. The way you've coded the Join, "gr1.join()" you're saying join (or run) the Main() thread to the end of this thread gr1 (or gr2 or gr3).
You can observe this effect but making the following small change to your code. Try un-commenting and re-commenting the block and see where the System.out prints. You will see that when the block is commented out the print statement appears at the top of the output and when you uncomment the block it prints at the bottom of the output, showing that the Join statement has kicked in and is stopping the Main() thread from continuing until the other threads have completed.

I dont think you can daisy-chain Joins together like you're trying to do - not in the Main() method anyway.



[ June 06, 2008: Message edited by: robert stannard ]
[ June 06, 2008: Message edited by: robert stannard ]
 
Mustafa Musaji
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah yeah I get it. That does make sense. I was making the mistake of thinking that calling gr1.join() was asking that thread to join on the main, but its asking the current thread you're running, in this case "main" to join on gr1 when it has finished.

Is that right?
 
robert stannard
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes thats exactly right. Its a bit confusing I know.

I dont know how you would daisy-chain gr1 to gr2 to gr3 to build up dependancies there, I dont think it can be done. I think thats what "synchronized" is good for.

I hope that helps.
 
Ram Manoj
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Robert, Mustafa and Reddy in taking this discussion further.

Hi Frank,

Originally posted by Frank Zito:
does this help (modifies main method though) ?



It works wonderfully. And the use of synchronized for ordering is brilliant.
But here the join() method does little.Even if we comment out join() methods, the threads are synchronized and seemingly join each other, but then I suppose the order is not guarenteed.

I have modified my code so it can accomodate multiple threads in an ordered way.


But then how do we accomplish the same task using join() method instead of using synchronized block code?

Ranchers please put in your views.
 
Karl Prenton
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ram Reddy is correct in suggesting that the join should be in the run method in order to control the order (doh!). The synch only prevents the block from being interrupted (by a similar thread).
Joining the main thread is not the issue, if I understand the problem correctly.
 
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
can anyone please give me a simple example to daisy chain threads?? although i have read threads in detail, i still have some issues writing join() and sychronized methods in program... is there any source where i could get details about join() and synchronized()...???
 
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Guys,

Try this example written by me.

I guess it solves your problem of Running 3 Thread T1, T2, T3 along with main Thread with a condition that T1 should finish first, T2 should finish Second and T3 should finish 3rd and main should finish last. It makes use of join() to accomplish the task.



Cheers !!
Saurabh
 
Ranch Hand
Posts: 331
Python Ruby Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Guide me why the foll code does compile(it even runs correctly at runtime and ends up throwing a out of memory exception)

 
What could go wrong in a swell place like "The Evil Eye"? Or with this tiny ad?
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic