Reputation: 4888
How to pass a parameter to a thread and get a return value?
public class CalculationThread implements Runnable {
int input;
int output;
public CalculationThread(int input)
{
this.input = input;
}
public void run() {
output = input + 1;
}
public int getResult() {
return output;
}
}
Somewhere else:
Thread thread = new Thread(new CalculationThread(1));
thread.start();
int result = thread.getResult();
Of course, thread.getResult()
doesn't work (it tries to invoke this method from the Thread
class).
How can I achieve this in Java?
Upvotes: 8
Views: 31373
Reputation: 16486
This a job for thread pools. You need to create a Callable<R>
which is Runnable
returning a value and send it to a thread pool.
The result of this operation is a Future<R>
which is a pointer to this job which will contain a value of the computation, or will not if the job fails.
public static class CalculationJob implements Callable<Integer> {
int input;
public CalculationJob(int input) {
this.input = input;
}
@Override
public Integer call() throws Exception {
return input + 1;
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
Future<Integer> result = executorService.submit(new CalculationJob(3));
try {
Integer integer = result.get(10, TimeUnit.MILLISECONDS);
System.out.println("result: " + integer);
} catch (Exception e) {
// interrupts if there is any possible error
result.cancel(true);
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.SECONDS);
}
Prints:
result: 4
Upvotes: 19
Reputation: 13731
Old school style
public class CalculationThread extends Thread {
int input;
int output;
public CalculationThread(int input){
this.input = input;
}
public void run() {
output = input + 1;
}
public int getResult() {
return output;
}
}
CalculationThread thread = new CalculationThread(1);
thread.start();
thread.join();
int result = thread.getResult();
Upvotes: 3
Reputation: 11280
The accepted answer is great. But it is not the simplest approach. There's no real need to use an ExecutorService if you just want to wait for the result of a thread. You can simply use java.util.concurrent.FutureTask
, which is basically a Runnable
wrapping a Callable
which also implements the Future
interface.
So step 1 is still make the calculation a Callable
:
public class Calculation implements Callable<Integer> {
private final int input;
public Calculation(int input) {
this.input = input;
}
@Override
public Integer call() throws Exception {
return input + 1;
}
}
So where you need the asynchronous calculation you can do :
FutureTask<Integer> task = new FutureTask<>(new Calculation(1561));
new Thread(task).start();
// ... do other stuff
// when I really need the result :
try {
int result = task.get(); // this will wait for the task to finish, if it hasn't yet.
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
e.getCause().printStackTrace(); // e.getCause() holds the exception that happened on the calculation thread
}
What the ExecutorService
adds is managing a pool of threads to run the task on, but under the hood of an ExecutorService
, basically the same thing happens.
Upvotes: 6
Reputation: 1
Use constructor and pass value by reference.
public CalculationThread(int[] input)
Do you want to pass the value of int
to the thread called CalculationThread
you should create a thread but if you pass a parameter by value the thread can use that value but you can't get the data back. Passing it by reference you can modify the value but not reference in the thread and the reference if it's available to both threads point to the value which is modifiable in both threads. Of cause you code should be synchronized to share the same reference.
Upvotes: 0
Reputation: 5348
You are looking for Callable. It's a Runnable on steroids, it can return a result. Check the javadoc:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html
Here is a tutorial: http://www.journaldev.com/1090/java-callable-future-example
Upvotes: 5