Meaningless Drivel is fun!*
The moose likes Beginning Java and the fly likes Can you access methods of a thread's target? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Can you access methods of a thread Watch "Can you access methods of a thread New topic
Author

Can you access methods of a thread's target?

Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
I have a class that implements Runnable and has an implementation of the run() method. It also has other methods that don't implement any method of Runnable. After I start the thread, is there any way to run one of those other methods? Since my thread of of type Thread I can't see those methods so I would somehow have to get a reference to the thread's target object first. So, another question would be, can I get a reference to a thread's *target* object and run its methods? (while the run() method is going, of course). Thanks!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

You can call other methods from within the run() method without any problems:
The thread only knows about the run() method, but the instance itself knows about all its methods.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
Yes, thank you, but I want the method that started the thread to call one of those methods! Unfortunately it has a reference only to the Thread object which as you say knows only about the run() method. I think it would need a reference to the *target* object and I can't see how to get that. If I could, I would be running other methods while the run() method is running. Maybe that's impossible, eh?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38007
    
  22
You mean something like this?Try it and see what happens. Put something into the run() method which takes a long time, and see whether the other call precedes the run() method's completion.
Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
Yikes! Things have taken a slight turn. I've been doing something like:

You see, since myThread is of type Thread I can't get to the methods of the target object of type MyRunnable. You presented a different way of starting the thread. It looks reasonable - I'll have to try it! Thanks.


Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

The only thing you didn't do in that code was to keep a reference to the MyRunnable object. If you had done that little thing, you could then have called methods on that reference.
Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
Paul - I had already tried that and I can call the method (concurrently) while the run() method was running just fine but it appeared to be a different object - as if the Thread object were a different one than the one I had a reference too. Maybe I made another mistake somewhere...

Ritchie - I tried your method but I don't think the mr.run() is creating a thread even though the class with the run() method implements Runnable. I appears to simply run the run() method normally. I made the run() method loop (and sleep) forever and it never returns. If it were a thread I would expect it to return immediately and run in the background.

In any case the ball's in my court - you'all have been mighty cordual and have given me a bunch of ideas to try out. Thanks very much and I'll post a reply if I find an elegant solution. You might have guessed that I'm trying to find a cool way to control my threads by setting their instance variables at various times while they're running.



Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Steve Dambrosio wrote:Paul - I had already tried that and I can call the method (concurrently) while the run() method was running just fine but it appeared to be a different object - as if the Thread object were a different one than the one I had a reference too. Maybe I made another mistake somewhere...


So did you try this:


Or did you try this:


In the first example, you've got two different objects, which matches your description of what you thought was happening. In the second example you have only one object.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38007
    
  22
If you declare it is of type Thread or Runnable, then you can only gain access to the methods of the Thread class or the Runnable interface. That is why I declared it as type MyRunnable.
Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
Paul - I tried the later as I should have, but must have done something else wrong cause it works now! I can manipulate the thread's instance variables and run its methods while the run() method is running. Now with each cycle the thread can consult its instance variables on what to do next... like stop for example! Thanks very very much for your help. Here's my code in case you're interested:


Output:
main started
whoAmI, threadName=steve, hashCode=11394033
Thread started, threadName=steve, hashCode=11394033
Thread looping, threadName=steve, hashCode=11394033
Thread looping, threadName=steve, hashCode=11394033
Thread looping, threadName=bob, hashCode=11394033
Thread looping, threadName=bob, hashCode=11394033
Thread looping, threadName=bob, hashCode=11394033
Thread looping, threadName=bob, hashCode=11394033
Thread ended, threadName=bob, hashCode=11394033
main ended
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Perfect!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

Well, almost. isStopped should be volatile, to prevent the run() method from using a cached value that will then not get updated.
Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
Rob Spoor wrote:Well, almost. isStopped should be volatile, to prevent the run() method from using a cached value that will then not get updated.

Boy, you guys are good. This is getting interesting. I suppose if it were important enough, all of the instance variables that control the behavior of the thread would have to updated and accessed atomically as a group. I.e. it wouldn't be good enough to define them all as volatile cause when the thread wakes up and says "what do I do next" the main thread may have updated some but not all of the variables. Having separate, synchronized "get group" and "set group" methods wouldn't work either since "get group" would have to be serialized with "set group". I suppose I'd need some kind of locking mechanism or perhaps one synchronized method that both sets the group and gets the group.... accessing... accesssing...
jon rozanski
Greenhorn

Joined: Dec 04, 2012
Posts: 5
Is there a way to do this for multiple threads? I want to change the runnable target of one thread, out of multiple, using the same reference to a runnable target, called MyRunnable.
The reason i refer to the same MyRunnable is because I instantiated the threads one by one
edit: threadsNum is configured number


I did this to have an iterable set of running threads:


and I want to do something along the lines of:


Any suggestions of where to look?
jon rozanski
Greenhorn

Joined: Dec 04, 2012
Posts: 5
First thought that came to mind was naming MyRunnable with the index name
like String nameofMyRunnable = "MyRunnable" + i;
and have i runnable targets, but i would rather something more elegant if possible
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Well, if all of the threads use the same MyRunnable object, then you already have a reference to it and you can call its methods.

However if you really meant for each thread to have its own instance of MyRunnable object, then creating an array which contains them would seem to me the easiest way of keeping track of all of them.
jon rozanski
Greenhorn

Joined: Dec 04, 2012
Posts: 5
yea, thats probably best. I do need a distinct instance of MyRunnable for every thread.
In my head the concept of having one MyRunnable for multiple threads is hazy.
If in one thread's running process I change MyRunnable, will that change that instance of MyRunnable and all of the other threads will now use this changed MyRunnable?
So, if that is true, then is it true that MyRunnable is not stored in the memory of any of threads but rather somewhere else? I guess I should understand how the memory works. Its synchronized with all the threads?
Steve Dambrosio
Greenhorn

Joined: Apr 02, 2009
Posts: 28
Jon,

First of all your loop (below) looks kinda worthless to me. Sure, I guess you are creating a new object with each loop but you are assigning it to the same variable name each time. So, when the loop is done you have one variable named "thread" that's pointing to the last object that you created. All of your other objects (threads) are now unreferenced and will be garbage collected. Correct me if I'm wrong, world!

Now, putting the variables in an array should work fine, e.g.
thread[0].doSomething()
thread[1].doSomethingElse()
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

jon rozanski wrote:In my head the concept of having one MyRunnable for multiple threads is hazy.
If in one thread's running process I change MyRunnable, will that change that instance of MyRunnable and all of the other threads will now use this changed MyRunnable?


Yes, that's right. If there's only one MyRunnable and all the threads are using it, then if you change it, all the threads will see the change. (There's some technical thread stuff about that but it doesn't really affect your question, so I'm going to skip that.)

So, if that is true, then is it true that MyRunnable is not stored in the memory of any of threads but rather somewhere else? I guess I should understand how the memory works. Its synchronized with all the threads?


Yes, that's exactly correct. All objects are stored in an area called the "heap", which is organized pretty much like a teenager's bedroom. So no object ever contains any other object. What they do contain is references to other objects -- think of the references as pointers, if you like. So in your example, each of the threads contains a reference to that single MyRunnable object. You might find that drawing pictures in which each object is a box, with arrows pointing from one object to another representing the references, makes it easier to picture what's going on.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Steve Dambrosio wrote: All of your other objects (threads) are now unreferenced and will be garbage collected. Correct me if I'm wrong, world!


Well, since you asked, actually active threads are not garbage collected. But as soon as they finish and become dead threads, then they can be garbage collected. It's as if the JVM keeps an array of active threads so they aren't actually unreferenced. (I say "as if" because I don't know how that's really implemented in a JVM, but it must be something like that.)

But the rest of what you said -- yup, that's how it is.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38007
    
  22
jon rozanski,
Your post was moved to a new topic.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can you access methods of a thread's target?
 
Similar Threads
Thread t=null !
Thread using Runnable Interface
Try this question I made up.
target Runnable of a thread
Instantiating a Thread page no 679