Muti thread join & get return values - java

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";
}

Related

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);
}

Callable with while loop

I need to provide code that using ExecutorService, Callable and Future will be doing some calculations and printing the partial results until defined condition is reached. First thing that comes to my mind is using while loop. Unfortunately as I understand ExecutorService.get() waits until the task is done, so I cannot do something like (pseudo code):
public Object call() throws Exception {
try {
while(!condition) {
//perform calc
return partialCalculationResult;
}
}
catch(InterruptedException e){
}
}
Could anyone guide me what's the proper direction I should go for?
This here:
while(!condition) {
//perform calc
return partialCalculationResult;
}
indicates a "hole" in your logic. This should probably go like this instead:
while(!condition) {
// perform computation
push intermediate results somewhere
}
return finalResult;
In other words: you are talking about two different elements here. For those "progress" updates you will need some kind of shared data structure; for example a Queue.
You see, in difference to other languages, there is no built-in "generator" concept that would allow you to yield values from a loop; like you can do in python or scala for example.
The dirty option is putting a System.out.println within the while loop.
The cleaner option would be a publish/subscriber pattern, like:
interface Subscriber {
void onPartialResult(double partialResult);
}
class SystemOutSubscriber implements Subscriber{
#Override
void onPartialResult(double partialResult) {
System.out.println(partialResult);
}
}
class YourCalculatorClass {
List<Subscriber> subscribers = ...
public Object call() throws Exception {
while(!condition) {
//perform calc
for(Subscriber s : subscribers) {
s.onPartialResult(partialCalculationResult);
}
}
}
}
You can use Thread.interrupt to stop the thread inside while loop and add remaining result in list
while(!condition){ list.add(addResultHere)
Thread.interrupt(); }
Below is a small example of using an ExecutorService
to push callable tasks. I push them inside a while loop now for the ease of the example, but they can come from anywhere. The callable itself uses the most silly easy example of course where it takes in a number. If the number is below 5, all is good, and we return a text. If not, we return nothing. When the future is evaluated and the result is empty, we shut down the ExecutorService and call it a day. So, this is an example of using an ExecutorService, Callable, and Future to do something at least similar to what I could discern from your explanation.
public ExecutorServiceTest() {
ExecutorService service = Executors.newCachedThreadPool();
int num = 0;
while (true) {
Future<Optional<String>> future = service.submit(new MyCallable(num++));
try {
Optional<String> result = future.get();
if (!result.isPresent()) {
service.shutdown();
break;
}
System.out.println(result.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
service.shutdown();
}
}
}
private static class MyCallable implements Callable<Optional<String>> {
private final int num;
MyCallable(int num) {
this.num = num;
}
#Override
public Optional<String> call() throws Exception {
if (num < 5)
return Optional.of("My number is " + num);
return Optional.empty();
}
}
public static void main(String[] args) {
new ExecutorServiceTest();
}

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.

Java signal/event mechanism to indicate some value is available

I have a generator class that owns a Thread in which a number of "records" to be generated is determined, then generates that many records (which get placed in a BlockingQueue for retrieval by another thread).
I'd like the other thread to know how many records are going to be generated (for sensible progress reporting among other things).
It seems Future gives me exactly the interface I'm after, but I'm new to Java, and not sure of the idiomatic way of implementing it.
My background is in C++/Win32, so I'd normally use a win32 "Event" (as created by CreateEvent(0, true, false, 0), with SetEvent and WaitForSingleObject for my signal and wait implementations). I've noticed Java has a CountDownLatch, but this somehow feels heavier than what I'm after (somewhat akin to using an int when I really want a boolean), and it seems unintuitive for this purpose (to me, anyway).
So here's my code using CountDownLatch and a Future. I've distilled my real code down a bit here (removed irrelevant implementation details and ignoring all error handling).
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public abstract class Generator {
private CountDownLatch numRecordsSignal = new CountDownLatch(1);
private int numRecords;
private BlockingQueue<Record> queue = new LinkedBlockingQueue<Record>();
public Generator() {
new Thread(new Runnable() {
#Override
public void run() {
numRecords = calculateNumRecords();
numRecordsSignal.countDown();
for (Record r : generateRecords()) {
try {
queue.put(r);
} catch (InterruptedException e) {
// [ ... snip ... ]
}
}
}
}).start();
}
public Future<Integer> numRecords() {
return new Future<Integer>() {
// Ignore cancel for now (It wouldn't make sense to cancel
// just this part of the Generator's work, anyway).
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
public Integer get() throws InterruptedException {
numRecordsSignal.await();
return numRecords;
}
public Integer get(long timeout, TimeUnit unit)
throws InterruptedException {
numRecordsSignal.await(timeout, unit);
return numRecords;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
// Since we can't cancel, just check the state of the
// signal
return numRecordsSignal.getCount() == 0;
}
};
}
public Record nextRecord() throws InterruptedException {
return queue.take();
}
/** --- Boring stuff below this line --- */
public interface Record { }
protected abstract int calculateNumRecords();
protected abstract Iterable<Record> generateRecords();
}
Now for my actual questions:
Is there a better mechanism than CountDownLatch for single-shot signalling?
I want callers to be able to either wait or poll on the result, but don't need them to be able to cancel the operation. Is Future the right way to expose this stuff?
Does any of this stuff look particularly "un-Java"? Am I on the wrong track completely?
Edit:
Just to clarify, I expect the caller to be able to do the following:
Generator gen = new Generator();
Integer numRecords = gen.numRecords().get(); // This call might block waiting for the result
numRecords = gen.numRecords().get(); // This call will never block, as the result is already available.
It's just a slow-to-initialise value I'm trying to implement. Once the "initialised" condition is met, it should latch. The value doesn't get re-evaluated once it's known.
Side comment
You should not start a thread in a constructor - it is very conceivable that the Generator object is not fully created when the thread starts, and the countdown latch could well be null for example. You can create the thread in the constructor, but should start it in a seperate method. Your calling code would become:
Generator g = new Generator();
g.start();
Your question
You are reimplementing a Future yourself, which is not necessary nor desirable in my opinion. I would redesign the class and make Generator implement Callable<Integer> and run it through an executor. That provides you with several things:
remove the threading logic from the Generator, which enables you a more efficient management of your threads at a higher level in your call stack
the integer is returned via the future in your calling code and you rely on the JDK to handle the implementation
I have assumed that it's ok to first populate the queue then return the integer
you can call future.get() as many times as you want - it will only block the first time it is called.
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(new GeneratorImpl()); //a concrete implementation of Generator
int numRecords = 0;
try {
numRecords = future.get(); //you can use a get with timeout here
} catch (ExecutionException e) {
//an exception happened in Generator#call()
} catch (InterruptedException e) {
//handle it
}
//don't forget to call executor.shutdown() when you don't need it any longer
}
public abstract class Generator implements Callable<Integer> {
private BlockingQueue<Record> queue = new LinkedBlockingQueue<Record>();
#Override
public Integer call() {
int numRecords = calculateNumRecords();
for (Record r : generateRecords()) {
try {
queue.put(r);
} catch (InterruptedException e) {
// [ ... snip ... ]
}
}
return numRecords;
}
public Record nextRecord() throws InterruptedException {
return queue.take();
}
/**
* --- Boring stuff below this line ---
*/
public interface Record {
}
protected abstract int calculateNumRecords();
protected abstract Iterable<Record> generateRecords();
}
EDIT
If you need to return numRecods asap, you can populate your queue in a separate thread:
public Integer call() {
int numRecords = calculateNumRecords();
new Thread(new Runnable() {
#Override
public void run() {
for (Record r : generateRecords()) {
try {
queue.put(r);
} catch (InterruptedException e) {
// [ ... snip ... ]
}
}
}
}).start(); //returns immediately
return numRecords;
}
The standard Java equivalents of "WaitOnSingleEvent()" and "SetEvent()" for Java threads are "wait()", "notify()" and "notifyAll()".
After looking at implementing my own signal mechanism and following the bread-crumb trail left by others doing the same thing, I came across the javadoc for AbstractQueuedSynchronizer, which includes a code snippet for a "BooleanLatch", which perfectly meets my needs:
class BooleanLatch {
private static class Sync extends AbstractQueuedSynchronizer {
boolean isSignalled() { return getState() != 0; }
protected int tryAcquireShared(int ignore) {
return isSignalled()? 1 : -1;
}
protected boolean tryReleaseShared(int ignore) {
setState(1);
return true;
}
}
private final Sync sync = new Sync();
public boolean isSignalled() { return sync.isSignalled(); }
public void signal() { sync.releaseShared(1); }
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
}
Doing a bit more searching, I found that a number of frameworks include a BooleanLatch (Apache Qpid being one). Some implementations (such as Atlassian's), are auto-resetting, which would make them inappropriate for my needs.
Standard observer notification pattern can be helpful here, if i understood your problem correctly.
For one shot signalling in this scenario Semaphore is better as it remembers the "signal".
Condition object [wait() is on a condition] won't remember the signal.
Semaphore numRecordsUpdated = new Semaphore(0);
In Generator
numRecordsUpdated.release();
In consumer
numRecordsUpdated.acquire();

Returning value from Thread

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);
}

Categories