aspose file tools*
The moose likes Threads and Synchronization and the fly likes How to make a thread return some value ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "How to make a thread return some value ?" Watch "How to make a thread return some value ?" New topic
Author

How to make a thread return some value ?

Prashant Bhardwaj
Greenhorn

Joined: Jul 25, 2006
Posts: 16
Hi,
Given java 1.4 enviornment.
The run method, as we know has a void return type.
I have a situation where I want to spawn multiple threads, all of them making
calls to methods in different EJBs.
The EJB calls return the same type of Object though.
So, if I put the calls in run method , how do I make this returned Object accessible to the calling API ?
Sorry, if you find it a stupid question.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18847
    
  40

The easiest way is probably to store it in a known location. For example, you can put it in some hashtable, with the thread name as the key. And this hashtable location could be set in the constructor of the runnable object.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Kevin Mangold
Greenhorn

Joined: Jan 13, 2005
Posts: 18
Henry's solution works. You can use wait() and notify()/notifyAll() with his solution too.

Another solution is to use a callback method. Use reflection, get a Method object of a target method, then when the thread needs to return something, invoke that method.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18570
    
    8

The callback method is a good idea, I have used that. Another way to do it without reflection is to put the callback method in an interface and pass the thread an instance of something that implements the interface. Like this:That defines the method the thread will call when it needs to "return" the result. Then the object that starts the thread can either implement this interface itself, or create an object that does that. I prefer the latter option, so it would look like this:And here's the Thread subclass that can use that interface:
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Look at Future in the API. Returning a value is exactly what it does.

Future hides all these details, but if you want to see them I'd rather use join() than wait() and notify() - if it fits your needs. Start a bunch of Threads with Runnables to do the work, join() all the Threads, call get() on your Runnable to get the result from each.

The callback is a different model because the callback happens on the child thread. If the part of the app that needs the result is event-driven, it may be just perfect. If you need the result back on the caller's thread, probably not.
[ April 20, 2007: Message edited by: Stan James ]

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Nikhil Jain
Ranch Hand

Joined: May 15, 2005
Posts: 385
Hi,
My requirement is that, I need to return some values which is processed by the child threads to the caller. How can this be achieved....


SCJP 1.4, SCWCD 1.4, SCBCD 1.5
Nikhil Jain
Ranch Hand

Joined: May 15, 2005
Posts: 385


What is wrong in the above code. I am trying to wait in CallThread class. I am trying to wait till the master thread completes. But somehow I always get the hashtable as blank...
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Stan]: Look at Future in the API. Returning a value is exactly what it does.

Yes, and that's the preferred solution in JDK 5 or later. But Prashant is limited to JDK 1.4. However...

[Shashank]: My requirement is that, I need to return some values which is processed by the child threads to the caller. How can this be achieved....

Are you using JDK 5 or greater? Have you looked at the Future class?

[Shashank]: What is wrong in the above code. I am trying to wait in CallThread class. I am trying to wait till the master thread completes. But somehow I always get the hashtable as blank...

I see two problems. One is that the code that tries to wait for the master thread is not guaranteed to work; the other is that waiting for the master thread is not enough. You want to wait until all the workers are completed, in order to see their effect.

For the first problem, how do you know that the master thread didn't already complete before you called wait()? You don't. If this happens, your wait() will last forever. In general you shouldn't call wait() without putting it in some sort of loop which checks a condition - in this case, check if the thread is still alive at all. However to wait until a thread is done, it's simpler to forget about wait and notify, and use the join() method instead. That's what it's there for.

For the second and more serious problem, you could insert some code at the end of the master thread that causes the master thread to wait until all its workers are done. Once again, this is easier done with join() instead of wait/notify:

[ July 09, 2007: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Nikhil Jain
Ranch Hand

Joined: May 15, 2005
Posts: 385
thanks,

but why did you use second loop for join. I could have done that in the first loop itself.

something like
_th.join(), & I guess If at all we use second loop, we may have to test whether the thread is still alive or not....
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Shashank]: but why did you use second loop for join. I could have done that in the first loop itself.

But if you did that, then you would join() the first thread before even starting the second. That means you'd wait until the first thread was dead before starting the second. And wait for the second to finish before starting the third, etc. In that case, why bother using threads at all?

[Shashank]: I guess If at all we use second loop, we may have to test whether the thread is still alive or not....

No. If a thread is already dead, then join() has no effect, and the program just moves on to whatever is next.
Kenneth Rowe
Greenhorn

Joined: Nov 13, 2009
Posts: 5

I tried the Paul Clapham example above and I got the following server error:
Exception in thread "Thread-146"
java.lang.NullPointerException
at sqlbuilder.ThreadWithResult.run(ThreadWithResult.java:33)
The actual code that I used had some slight differences.
If someone could take a look at what I've done and tell me what I am doing wrong, I would really appreciate it.\


Here is Caller.java:
-------
package sqlbuilder;

public class Caller {
private String threadResult;

// later, in some method, create a result setter:
ResultSetter setter = new ResultSetter() {
public void setResult(String result) {
threadResult = result;
}
};
}

Here is ResultSetter :
-----
package sqlbuilder;

public interface ResultSetter {
public void setResult(String result);
}

Here is ThreadWithResult
---------
package sqlbuilder;

public class ThreadWithResult extends Thread {
private ResultSetter setter;

public void setResultSetter(ResultSetter setter) {
this.setter = setter;
System.out.println("21-threadwithresult: "+setter);
}

public void run() {

String sTime2 = "Hello from Ken";
System.out.println("28-threadwithresult");
System.out.println(sTime2);
setter.setResult(sTime2);
System.out.println("32-threadwithresult");
}
}


Here is the code that calls the programs above:
------
ResultSetter setter = null;
System.out.println("report Excel line 398");

ThreadWithResult thread = new ThreadWithResult();
System.out.println("401-report Excel");

thread.setResultSetter(setter) ;
System.out.println("404-report Excel");

thread.start();

Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Hi Kenneth,

Welcome to JavaRanch. A few pointers to help you get answers in the future. First please DontWakeTheZombies - it helps keep people see your question when you make a new post and keeps people on target for answering your question rather than a 2 year old one. Second, next time you post code you should UseCodeTags to improve readability.

The problem you have is because you are referencing an object named setter in the run() method but you never instantiate the object. In your running code you create a ResultSetter reference, assign it a null value and pass that null to the thread. In the thread you try to use the null value as if it were an object so you get the NPE.

You need to create a class which implements the interface, instantiate it to creat an object, and store that object in the setter reference.


Steve
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to make a thread return some value ?