• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to make a thread return some value ?

 
Prashant Bhardwaj
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Marshal
Pie
Posts: 21490
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Kevin Mangold
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 21416
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Nikhil Jain
Ranch Hand
Posts: 389
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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....
 
Nikhil Jain
Ranch Hand
Posts: 389
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


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
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[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 ]
 
Nikhil Jain
Ranch Hand
Posts: 389
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[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
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

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
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic