Returning value from Thread - java

I have a method with a HandlerThread. A value gets changed inside the Thread and I'd like to return it to the test() method. Is there a way to do this?
public void test()
{
Thread uiThread = new HandlerThread("UIHandler"){
public synchronized void run(){
int value;
value = 2; //To be returned to test()
}
};
uiThread.start();
}

Usually you would do it something like this
public class Foo implements Runnable {
private volatile int value;
#Override
public void run() {
value = 2;
}
public int getValue() {
return value;
}
}
Then you can create the thread and retrieve the value (given that the value has been set)
Foo foo = new Foo();
Thread thread = new Thread(foo);
thread.start();
thread.join();
int value = foo.getValue();
tl;dr a thread cannot return a value (at least not without a callback mechanism). You should reference a thread like an ordinary class and ask for the value.

You can use a local final variable array. The variable needs to be of non-primitive type, so you can use an array. You also need to synchronize the two threads, for example using a CountDownLatch:
public void test()
{
final CountDownLatch latch = new CountDownLatch(1);
final int[] value = new int[1];
Thread uiThread = new HandlerThread("UIHandler"){
#Override
public void run(){
value[0] = 2;
latch.countDown(); // Release await() in the test thread.
}
};
uiThread.start();
latch.await(); // Wait for countDown() in the UI thread. Or could uiThread.join();
// value[0] holds 2 at this point.
}
You can also use an Executor and a Callable like this:
public void test() throws InterruptedException, ExecutionException
{
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> callable = new Callable<Integer>() {
#Override
public Integer call() {
return 2;
}
};
Future<Integer> future = executor.submit(callable);
// future.get() returns 2 or raises an exception if the thread dies, so safer
executor.shutdown();
}

What you are looking for is probably the Callable<V> interface in place of Runnable, and retrieving the value with a Future<V> object, which also lets you wait until the value has been computed. You can achieve this with an ExecutorService, which you can get from Executors.newSingleThreadExecutor() .
public void test() {
int x;
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Integer> result = es.submit(new Callable<Integer>() {
public Integer call() throws Exception {
// the other thread
return 2;
}
});
try {
x = result.get();
} catch (Exception e) {
// failed
}
es.shutdown();
}

How about this solution?
It doesn't use the Thread class, but it IS concurrent, and in a way it does exactly what you request
ExecutorService pool = Executors.newFixedThreadPool(2); // creates a pool of threads for the Future to draw from
Future<Integer> value = pool.submit(new Callable<Integer>() {
#Override
public Integer call() {return 2;}
});
Now all you do is say value.get() whenever you need to grab your returned value, the thread is started the very second you give value a value so you don't ever have to say threadName.start() on it.
What a Future is, is a promise to the program, you promise the program that you'll get it the value it needs sometime in the near future
If you call .get() on it before it's done, the thread that's calling it will simply just wait until it's done

From Java 8 onwards we have CompletableFuture.
On your case, you may use the method supplyAsync to get the result after execution.
Please find some reference here.
CompletableFuture<Integer> completableFuture
  = CompletableFuture.supplyAsync(() -> yourMethod());
completableFuture.get() //gives you the value

If you want the value from the calling method, then it should wait for the thread to finish, which makes using threads a bit pointless.
To directly answer you question, the value can be stored in any mutable object both the calling method and the thread both have a reference to. You could use the outer this, but that isn't going to be particularly useful other than for trivial examples.
A little note on the code in the question: Extending Thread is usually poor style. Indeed extending classes unnecessarily is a bad idea. I notice you run method is synchronised for some reason. Now as the object in this case is the Thread you may interfere with whatever Thread uses its lock for (in the reference implementation, something to do with join, IIRC).

Using Future described in above answers does the job, but a bit less significantly as f.get(), blocks the thread until it gets the result, which violates concurrency.
Best solution is to use Guava's ListenableFuture. An example :
ListenableFuture<Void> future = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1, new NamedThreadFactory).submit(new Callable<Void>()
{
#Override
public Void call() throws Exception
{
someBackgroundTask();
}
});
Futures.addCallback(future, new FutureCallback<Long>()
{
#Override
public void onSuccess(Long result)
{
doSomething();
}
#Override
public void onFailure(Throwable t)
{
}
};

With small modifications to your code, you can achieve it in a more generic way.
final Handler responseHandler = new Handler(Looper.getMainLooper()){
#Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Result from UIHandlerThread:"+(int)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
HandlerThread handlerThread = new HandlerThread("UIHandlerThread"){
public void run(){
Integer a = 2;
Message msg = new Message();
msg.obj = a;
responseHandler.sendMessage(msg);
System.out.println(a);
}
};
handlerThread.start();
Solution :
Create a Handler in UI Thread,which is called as responseHandler
Initialize this Handler from Looper of UI Thread.
In HandlerThread, post message on this responseHandler
handleMessgae shows a Toast with value received from message. This Message object is generic and you can send different type of attributes.
With this approach, you can send multiple values to UI thread at different point of times. You can run (post) many Runnable objects on this HandlerThread and each Runnable can set value in Message object, which can be received by UI Thread.

Here is a cleaner approach, you just need a bit change to your existing code. The goal is to get the result from the the Thread. It doesn't really have to be return a result. Instead, using a callback style to take that result and do further processing.
public class Test {
public static void main(String[] args) {
String str = args[0];
int count = 0;
Thread t = new Thread(() ->
someFuncToRun(str, count, (value) -> {
System.out.println(value);
return value;
}));
t.start();
}
// Here I even run a recursive method because run things in the
// a thread sometime is to delegate those heavy lifting elsewhere
public static String someFuncToRun(String str, int ctn, Callback<String> p) {
++ctn;
if (ctn == 10) {
System.out.println("End here");
return p.cb(str);
}
System.out.println(ctn + " times");
return someFuncToRun(str + " +1", ctn, p);
}
}
// The key is here, this allow you to pass a lambda callback to your method
// update: use generic to allow passing different type of data
// you could event make it <T,S> so input one type return another type
interface Callback<T> {
public T cb(T a);
}

Related

How to make Java runnable call a callback from the main thread, and not the background thread?

I was doing some thought experiment and here is my MyRunnable class:
class MyRunnable implements Runnable {
private final Integer mNumber;
private final CompleteHandler<Integer> mCallback;
public MyRunnable(Integer i, CompleteHandler<Integer> ch) {
mNumber = i;
mCallback = ch;
}
public void run() {
int sum = 0;
for (int i = 1; i <= mNumber; i++) {
sum += i;
}
mCallback.onFinished(sum);
}
}
This will be executed by a background thread which I create on the main thread, under the execute() method
public class Demo implements CompleteHandler<Integer>{
public static void main(String[] args) {
Demo d = new Demo();
d.execute();
}
#Override
public void onFinished(Integer i) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName); // thread-0
}
public void execute() {
MyRunnable mr = new MyRunnable(10, this);
Thread t = new Thread(mr);
t.start();
}
}
As you can see, the MyRunnable calls onFinished() when the task is finished. Is there any way I can have the background thread to call this on the main thread? I know I can do similar thing with callables, but right now I want to know if this is possible with runnables,
thank you
Johannes: Take a look at CompletableFuture...
Brendon: I'm more interested in seeing how it work on code
Here's a simplistic implementation that ignores the issue of exceptions. (Pardon me if it's not actually valid Java code.)
class CompletableFuture<ValueType> {
private Object lock = new Object();
private boolean is_completed = false;
private ValueType completed_value;
public synchronized void complete(ValueType v) {
completed_value = v;
is_completed = true;
notifyAll();
}
public synchronized ValueType await() {
while (! is_completed) {
wait();
}
return completed_value;
}
}
The idea is, the client thread creates a CompletableFuture instance, cf, and somehow passes it to the server thread, possibly along with other args that tell the server thread what to do. Then the client thread goes off to do other, unrelated things.
Meanwhile, the server thread does its thing, eventually produces a result, r, and then it calls cf.complete(r).
At some point, the client thread finishes doing whatever else it was doing, and now it needs the result, so it calls cf.await(). Either one of two things happen at that point:
The server already has set the is_completed flag, in which case, the client immediately gets the result, OR
The server has not yet finished, so the client goes in to the wait() loop to wait for it.
When you're looking at application code, you usually never see the part where the client thread creates the Future object or passes it to the other thread. That usually is all taken care of inside the library call when the client submits a task to a thread pool.

How I can return value from Thread [duplicate]

I have a method with a HandlerThread. A value gets changed inside the Thread and I'd like to return it to the test() method. Is there a way to do this?
public void test()
{
Thread uiThread = new HandlerThread("UIHandler"){
public synchronized void run(){
int value;
value = 2; //To be returned to test()
}
};
uiThread.start();
}
Usually you would do it something like this
public class Foo implements Runnable {
private volatile int value;
#Override
public void run() {
value = 2;
}
public int getValue() {
return value;
}
}
Then you can create the thread and retrieve the value (given that the value has been set)
Foo foo = new Foo();
Thread thread = new Thread(foo);
thread.start();
thread.join();
int value = foo.getValue();
tl;dr a thread cannot return a value (at least not without a callback mechanism). You should reference a thread like an ordinary class and ask for the value.
You can use a local final variable array. The variable needs to be of non-primitive type, so you can use an array. You also need to synchronize the two threads, for example using a CountDownLatch:
public void test()
{
final CountDownLatch latch = new CountDownLatch(1);
final int[] value = new int[1];
Thread uiThread = new HandlerThread("UIHandler"){
#Override
public void run(){
value[0] = 2;
latch.countDown(); // Release await() in the test thread.
}
};
uiThread.start();
latch.await(); // Wait for countDown() in the UI thread. Or could uiThread.join();
// value[0] holds 2 at this point.
}
You can also use an Executor and a Callable like this:
public void test() throws InterruptedException, ExecutionException
{
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> callable = new Callable<Integer>() {
#Override
public Integer call() {
return 2;
}
};
Future<Integer> future = executor.submit(callable);
// future.get() returns 2 or raises an exception if the thread dies, so safer
executor.shutdown();
}
What you are looking for is probably the Callable<V> interface in place of Runnable, and retrieving the value with a Future<V> object, which also lets you wait until the value has been computed. You can achieve this with an ExecutorService, which you can get from Executors.newSingleThreadExecutor() .
public void test() {
int x;
ExecutorService es = Executors.newSingleThreadExecutor();
Future<Integer> result = es.submit(new Callable<Integer>() {
public Integer call() throws Exception {
// the other thread
return 2;
}
});
try {
x = result.get();
} catch (Exception e) {
// failed
}
es.shutdown();
}
How about this solution?
It doesn't use the Thread class, but it IS concurrent, and in a way it does exactly what you request
ExecutorService pool = Executors.newFixedThreadPool(2); // creates a pool of threads for the Future to draw from
Future<Integer> value = pool.submit(new Callable<Integer>() {
#Override
public Integer call() {return 2;}
});
Now all you do is say value.get() whenever you need to grab your returned value, the thread is started the very second you give value a value so you don't ever have to say threadName.start() on it.
What a Future is, is a promise to the program, you promise the program that you'll get it the value it needs sometime in the near future
If you call .get() on it before it's done, the thread that's calling it will simply just wait until it's done
From Java 8 onwards we have CompletableFuture.
On your case, you may use the method supplyAsync to get the result after execution.
Please find some reference here.
CompletableFuture<Integer> completableFuture
  = CompletableFuture.supplyAsync(() -> yourMethod());
completableFuture.get() //gives you the value
If you want the value from the calling method, then it should wait for the thread to finish, which makes using threads a bit pointless.
To directly answer you question, the value can be stored in any mutable object both the calling method and the thread both have a reference to. You could use the outer this, but that isn't going to be particularly useful other than for trivial examples.
A little note on the code in the question: Extending Thread is usually poor style. Indeed extending classes unnecessarily is a bad idea. I notice you run method is synchronised for some reason. Now as the object in this case is the Thread you may interfere with whatever Thread uses its lock for (in the reference implementation, something to do with join, IIRC).
Using Future described in above answers does the job, but a bit less significantly as f.get(), blocks the thread until it gets the result, which violates concurrency.
Best solution is to use Guava's ListenableFuture. An example :
ListenableFuture<Void> future = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1, new NamedThreadFactory).submit(new Callable<Void>()
{
#Override
public Void call() throws Exception
{
someBackgroundTask();
}
});
Futures.addCallback(future, new FutureCallback<Long>()
{
#Override
public void onSuccess(Long result)
{
doSomething();
}
#Override
public void onFailure(Throwable t)
{
}
};
With small modifications to your code, you can achieve it in a more generic way.
final Handler responseHandler = new Handler(Looper.getMainLooper()){
#Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Result from UIHandlerThread:"+(int)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
HandlerThread handlerThread = new HandlerThread("UIHandlerThread"){
public void run(){
Integer a = 2;
Message msg = new Message();
msg.obj = a;
responseHandler.sendMessage(msg);
System.out.println(a);
}
};
handlerThread.start();
Solution :
Create a Handler in UI Thread,which is called as responseHandler
Initialize this Handler from Looper of UI Thread.
In HandlerThread, post message on this responseHandler
handleMessgae shows a Toast with value received from message. This Message object is generic and you can send different type of attributes.
With this approach, you can send multiple values to UI thread at different point of times. You can run (post) many Runnable objects on this HandlerThread and each Runnable can set value in Message object, which can be received by UI Thread.
Here is a cleaner approach, you just need a bit change to your existing code. The goal is to get the result from the the Thread. It doesn't really have to be return a result. Instead, using a callback style to take that result and do further processing.
public class Test {
public static void main(String[] args) {
String str = args[0];
int count = 0;
Thread t = new Thread(() ->
someFuncToRun(str, count, (value) -> {
System.out.println(value);
return value;
}));
t.start();
}
// Here I even run a recursive method because run things in the
// a thread sometime is to delegate those heavy lifting elsewhere
public static String someFuncToRun(String str, int ctn, Callback<String> p) {
++ctn;
if (ctn == 10) {
System.out.println("End here");
return p.cb(str);
}
System.out.println(ctn + " times");
return someFuncToRun(str + " +1", ctn, p);
}
}
// The key is here, this allow you to pass a lambda callback to your method
// update: use generic to allow passing different type of data
// you could event make it <T,S> so input one type return another type
interface Callback<T> {
public T cb(T a);
}

Muti thread join & get return values

I'm trying to do multiple heavy calculations using threads.
Then I need to do something with the results after making sure all threads have finished its job.
Here's the basic code:
private class Runner implements Runnable {
private String _result = "fail";
public String get_results() {
return _result;
}
public void run() {
_result = "do complex calculation";
}
}
public void test() {
List<Thread> threads = new ArrayList<Thread>();
List<Runner> threadObjects = new ArrayList<Runner>();
for (int i = 0; i < 10; i++) {
Runner runner = new Runner();
Thread t = new Thread(runner);
t.start();
threads.add(t);
threadObjects.add(runner);
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException ex) {
}
}
for (Runner threadObject : threadObjects) {
System.out.println(threadObject.get_results());
}
}
My question is, is above snippet a common or a good approach to get calculation value?
If not please suggest a better ones.
Also sometimes I got runner.get_results() reponse = "fail", it seems calculation does not processed at all.
Thanks
You can use an ExecutorService such as the ScheduledThreadPoolExecutor;
ExecutorService executor = new ScheduledThreadPoolExecutor(numOfThreads);
With numOfThreads being the number of threads you want sitting in the thread pool.
You can then use the submit(Callable<T> task) method provided by the ScheduledThreadPoolExecutor class to execute the calculation.
You would then have a Callable implementation of your calculation and pass it to the submit() method in ExecutorService to execute the calculation;
class Calculation implements Callable {
#Override
public Object call() throws Exception { // The signature can be changed to return a different type (explained at the end)
return "do complex calculation";
}
}
As we can see from the method signature of the submit(Callable<T> task) method it returns a Future.
public <T> Future<T> submit(Callable<T> task)
The get() method of the Future class will return the result upon successful completion. This would ensure that your calculation completed before reading it.
A further note on the return type of the call() method;
Although this returns Object there is nothing stopping you changing the type of object it returns (this is known as co-variant returns)
For example the following is perfectly legal:
#Override
public String call() throws Exception {
return "do complex calculation";
}

Get Return Value from Runnable(Thread) in Java [duplicate]

This question already has answers here:
Returning value from Thread
(9 answers)
Closed 7 years ago.
Is there a way for me to pass the value of "r" once this thread completes? I believe I did this 9 or 10 months ago on another project but for the l ife of me I cannot remember the project of find the code. I've spent about 5 hours digging through code and googling but have fell short on a solution and since I do not develop in Java\Android often, this has completely slipped my mind.
Below is my code and what I think I remember from the last time I did this. I kind of remember a ".call()" or ".get()" but after trying to find something in the android docs. I'm not so sure. I could only find "callable".
public void updateUserProfile(){
if(checkFields(){
//Do Something
}else{
//Do Something
}
}
public boolean checkFields(){
Boolean r = false;
Runnable run = new Runnable(){
//Boolean r;
#Override
public void run() {
//Or boolean r;
//get value of r.
r = php.UpdateProfile.updateProfile(user_id, user_email);
}
};
new Thread(run).start();
return r; //run.get(r)?
}
What you are doing is creating an instance of an anonymous inner class implementing Runnable. As such you can access the fields of the containing class. Store the result of your code in one of those.
Of course be careful to synchronise access to this result variable between your main thread and the one you create here.
public class TestThreads {
static int r = 0;
public static void main(String[] args) {
Runnable run = new Runnable() {
public void run() {
r = 20;
}
};
Thread t = new Thread(run);
t.start();
try {
t.join();
}
catch(InterruptedException e) {
return;
}
System.out.println("Result: " + r);
}
}
You cannot return values from method which has return type Void.
Use Handler class to send messages, and from thread's run method, call handler.sendMessage() and handle this message on onHandleMessage of Handler
Handler Document link
Handler example
Try with Future, Callable, ExecuterService ... This might help http://www.journaldev.com/1090/java-callable-future-example
Runnable does not return. You will need to use Future that implements Callable or use FutureTask.
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
FutureTask<String> future =
new FutureTask(new Callable() {
public String call() {
String res = ...;
return res;
});
pool.execute(future);
String res = future.get();
// use the line below if you want to set a timeout for the task
String res = future.get(timeoutmillis, TimeUnit.MILLISECONDS);
I ended up using AsyncTask. Was hoping to keep it super simple because of support requirements but AsyncTask did what I needed it to.
private class updateUserProfile extends AsyncTask<Boolean, Boolean, Boolean>{
#Override
protected Boolean doInBackground(Boolean... params) {
return php.UpdateProfile.updateProfile(etEditAddress.getText().toString(),
etEditCity.getText().toString(),
spnStates.getSelectedItem().toString(), etEditZip.getText().toString(), etEditPhone.getText().toString(), etEditAddress.getText().toString());;
}
public void onPostExecute(String result) {
// execution of result of Long time consuming operation
Toast.makeText(MyAccount.this, result.toString(), Toast.LENGTH_LONG).show();
}
}

Return result of thread to a separate thread

For example if I have thread A and thread B. Thread A is my main thread where most of the application runs but when I need a value fetched from MySQL or another external source I create a new thread (thread B).
What is the best way of returning the value from thread B to thread A for further processing without causing thread A to wait until the value is available?
If you have a single task that needs to be done, you can use a Future and have the other Thread poll the (non-blocking) isDone() method whenever it is convenient.
If that task is executed frequently or you have many tasks to execute, using a ConcurrentLinkedQueue might be a better idea, which also comes in a variant that supports blocking till a result is delivered as LinkedBlockingQueue. Again: polling on the list whenever it is convenient will do the trick.
If you do not want to poll, you can instead work with a callback-functionality. For example if you use a Swing GUI, you can have the DB thread call invokeLater from the SwingUtilities class, so processing the request is done on the main Swing thread at the next possible time.
This is based on the EventQueue class, which might be more convenient to use in certain other scenarios.
Use a Queue, A will periodically poll the queue, B can put values to queue asynchroneously
You can use ScheduledThreadPoolExecutor which will return Future and you dont need to wait.
Sample Usage (From java Docs on Future)
interface ArchiveSearcher { String search(String target); }
class App {
ExecutorService executor = ...
ArchiveSearcher searcher = ...
void showSearch(final String target)
throws InterruptedException {
Future<String> future
= executor.submit(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
displayOtherThings(); // do other things while searching
try {
displayText(future.get()); // use future
} catch (ExecutionException ex) { cleanup(); return; }
}
}
Same can be achieved from Future task too(visit above link, example are from there only)
The FutureTask class is an implementation of Future that implements Runnable, and so may be executed by an Executor. For example, the above construction with submit could be replaced by:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
executor.execute(future);
For thread B, declare a class that implements Runnable. For example:
public class MyClass implements Runnable
{
private String input = null;
private String output = null;
public MyClass(String input)
{
this.input = input;
}
public String getOutput()
{
return output;
}
public void run()
{
output = func(input);
}
}
In thread A (which is your main thread), start thread B, and wait for it to complete only where you actually need its output. For example:
public String myFunc(String input) throws Exception
{
MyClass object = new MyClass(input);
Thread thread = new Thread(object);
thread.start();
// Do whatever you wanna do...
// ...
// ...
// And when you need the thread's output:
thread.join();
return object.getOutput();
}
If you don't want to deal with executors, just create a FutureTask and pass it to a new thread.
FutureTask<String> f = new FutureTask<String>(new Callable<String>() {
#Override
public String call() {
return "";
}
});
new Thread(f).start();
while (Thread.currentThread().isInterrupted()) {
if (f.isDone()) {
System.out.println(f.get());
break;
}
//do smth else
}
Organize your main thread as an event loop:
BlockingQueue<Runnable> eventQueue=
new LinkedBlockingQueue<>();
for (;;) {
Runnable nextEvent=eventQueue.take();
nextEvent.run();
}
Thread B:
Result r=fetchFromDB();
eventQueue.put(new ResultHandler(r));
where ResultHandler is a Runnable which knows how to handle the result.

Categories