aspose file tools*
The moose likes Beginning Java and the fly likes Thread Constructor - Usage of Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Thread Constructor - Usage of "this"" Watch "Thread Constructor - Usage of "this"" New topic
Author

Thread Constructor - Usage of "this"

Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
See the code below:

[Added code tags and formatted - see UseCodeTags]

Output:

Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Main Thread: 4
Main Thread: 3
Main Thread: 2
Main Thread: 1
Main thread exiting.

In "Line(1) above, if I write,

t = new Thread(this, "Demo Thread"); the output is

run:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
BUILD SUCCESSFUL (total time: 5 seconds)


I cannot understand what "this" does to this code. What happens when I don't use "this" there? Please explain.



Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3646
    
  15
Take a look at the javadoc for the Thread.run method.


Joanne
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39393
    
  28
My, what a load of illegible code!
Have you read about the Thread constructor, and what parameters it takes?
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Hello,

Yes, I have read about the constructor and what parameters it takes. It has 2 forms (at least 2 that I know of), one is taking just "String threadname". the other taking "Runnable Threadob, String threadname". In this scenario, passing "this, "demo thread" would invoke the 2nd constructor.

I understand that, but I don't know how the 2nd thread never starts to run if I invoke the 1st constructor.
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Sorry about my earlier code being too lengthy and illegible. I've tried to shorten it here.



The above code will print:

Main Thread
Child Thread

When I rewrite Line (1) as "t = new Thread("Demo Thread");", the Child Thread never gets started. I don't understand what "this" does to the code.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4420
    
    8

In your first version, on line 8 you create a new Thread, and you start it. Nowhere do you actually tell that thread to do anything. Why would it run your child thread.

In the second version, though, you're saying "create a new thread, using the current object as a Runnable" (which is possible because NewThread implements Runnable). If you pass a Runnable into a Thread, then when it is started it will execute the run() method of that Runnable. So now you've told it to do something, and it can do it.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4420
    
    8

A bit more info: when a Thread is started, its run() method is executed. And roughly speaking, this is what it looks like (ignoring lots of the details):
So a Thread does nothing unless you do one of two things:

- pass in a Runnable (which is nearly always the better approach)
- inherit from Thread and override the default run() method
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Thank you, Matt. I am still a bit confused.

"In your first version, on line 8 you create a new Thread, and you start it. Nowhere do you actually tell that thread to do anything. Why would it run your child thread. "

What does the "this" do that prompts the child to start running? I thought calling the start() method always called run() automatically.

Why does passing "this" alone call run()?
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3646
    
  15
Prasanna Raman wrote:Hello,

Yes, I have read about the constructor and what parameters it takes. It has 2 forms (at least 2 that I know of), one is taking just "String threadname". the other taking "Runnable Threadob, String threadname". In this scenario, passing "this, "demo thread" would invoke the 2nd constructor.

I understand that, but I don't know how the 2nd thread never starts to run if I invoke the 1st constructor.

If you had taken my advice as well as Campbell's, you would have got a simplified version of what Matthew has just told you.
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3646
    
  15
Prasanna Raman wrote:What does the "this" do that prompts the child to start running? I thought calling the start() method always called run() automatically.

Why does passing "this" alone call run()?

A run method is always called when you call the start method. The only difference is which run method. When you pass 'this' (or any other reference to a Runnable object) to the constructor, the run method of that object will be called. If you don't pass a Runnable object to the constructor, the run method of the Thread class will be called which does nothing.
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Hello Joanne,

Yes, I did read the Javadoc, but I am not understanding this:

"public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread."

The above says, calling start() will start run(), which is what I thought my code would do even if I didn't use "this".

But Javadoc for run() does say

"If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns."

My simple brain only tells me that the above 2 are contradictory with the first one telling that run() is called when start() is called and the 2nd one telling that run() is not called on a Runnable object.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Prasanna Raman wrote:What does the "this" do that prompts the child to start running?
Think about it: at that line of code, what does this mean? What feature does this have that relates to what everyone is telling you?
I thought calling the start() method always called run() automatically.
It does. But whose run() method? If you don't pass it a Runnable, how does it know what run() method to execute?
Why does passing "this" alone call run()?
It doesn't. Passing this tells the Thread where to find the code to run (in the Runnable's run() method.). Calling start() makes it happen.


Steve
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39393
    
  28
Prasanna Raman wrote:Sorry about my earlier code being too lengthy and illegible. I've tried to shorten it here.
. . .
Shorter, maybe. Easier to read, no. Because of inappropriate indentation, that is probably more difficult to read.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Prasanna Raman wrote:Hello Joanne,

Yes, I did read the Javadoc, but I am not understanding this:

"public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread."

The above says, calling start() will start run(), which is what I thought my code would do even if I didn't use "this".

But Javadoc for run() does say

"If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns."

My simple brain only tells me that the above 2 are contradictory with the first one telling that run() is called when start() is called and the 2nd one telling that run() is not called on a Runnable object.

No, not contradictory at all. You have two Objects. A Thread object and an instance of the poorly named NewThread object (poorly named because it is not, in fact, a Thread). Both objects have a run() method. Calling Thread#start() causes the Thread object's run() method to execute in a new OS level thread. Passing a Runnable into the constructor causes the Thread's run() method to execute the Runnable's run() method (in the new OS level thread). When you pass this you are passing the instance of the NewThread, which is a Runnable, and so are causing it's run() method to be called from the Thread's run() method, which is called in a new OS level thread created by calling Thread#start().
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Yes, sorry Campbell. Will see to it that it's indented when I post my next code. Thanks for pointing this out.
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Thank you for the replies. I think I am getting closer here.

So, passing "this" would make the program call the run() method on my current object. That run() method is the code I've written in the program below the NewThread() constructor.

But, if I don't pass "this", then it's just calling the thread class's run() method, which will do nothing. The run() method in my code is never entered into.

Is passing "this" similar to doing "RunnableOb.t.run()"? and not passing just means calling "t.run()"?
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3646
    
  15
Prasanna Raman wrote:Thank you for the replies. I think I am getting closer here.

So, passing "this" would make the program call the run() method on my current object. That run() method is the code I've written in the program below the NewThread() constructor.

But, if I don't pass "this", then it's just calling the thread class's run() method, which will do nothing. The run() method in my code is never entered into.

Is passing "this" similar to doing "RunnableOb.t.run()"? and not passing just means calling "t.run()"?

Almost there. Have a look at the code that Matthew posted. The run method of the Thread class is always called. It then calls the run method of the Runnable object if there is one or just returns if there isn't.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39393
    
  28
Prasanna Raman wrote:Yes, sorry Campbell. Will see to it that it's indented when I post my next code. Thanks for pointing this out.
Apologies accepted We have some suggestions about indentation, etc, which will make your code much easier to read.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Prasanna Raman wrote:Is passing "this" similar to doing "RunnableOb.t.run()"? and not passing just means calling "t.run()"?


I have no idea what that annotation means. The this keyword is just a reference to the current instance - so in your example it is just a reference to the NewThread object which is being created. That NewThread object is a Runnable, so it behaves just like passing a Runnable into the Thread constructor. There is nothing special about using this.

To help isolate concepts, keep this and Thread out of it. Let's say you have a class like this:

It is a simple class holding a single method designed to do some specific action. Now, let's say you have a slightly more complicated class, like this:

This worker is designed so you call worker.startWorking() to do some work. If there is a callbackObject, the work is to call that object's callbackMethod(). Otherwise it does nothing.

Finally, let's say you have this code to make it run:

This code just creates an instance of Callback, passes it to an instance of Worker, then tells worker to startWorking(). Assuming I didn't make any coding mistakes this will print Do some work to the console.

Can you follow what is happening in this code? This is what is happening in your code as well, except Worker is Thread, Callback is Runnable as implemented by NewThread, and you do the work from Main inside NewThread's constructor (yeah, there are some differences but they don't seem to be where you are having trouble).
Prasanna Raman
Ranch Hand

Joined: Sep 05, 2010
Posts: 335
Thank you so much, Steve! That example made it very clear to me

Thank you everyone for persisting with me!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Thread Constructor - Usage of "this"