Looking at the javadocs it just says
<T> Future<T> submit(Runnable task, T result)
Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return the given result upon successful completion.
Parameters:
task - the task to submit
result - the result to return
but what does it do with result? does it store anything there? does it just use the type of result to specify the type of Future<T>?
It doesn't do anything with the result - just holds it. When the task successfully completes, calling future.get() will return the result you passed in.
Here is the source code of Executors$RunnableAdapter, which shows that after the task has run, the original result is returned:
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
And yes, the generic type of the result should match that of the returned Future.
Runnable does not return anything and Future must return something so this method allows you to predefine the result of the returned future.
If you don't want to return a thing you can return null and I think the Void type exists to express that kind of things.
Future<Void> myFuture = executor.submit(myTask, null);
You know myFuture.get() will return null in this case but only after the task has been run, so you would use it to wait and throw any exception that were thrown in the task.
try {
myFuture.get();
// After task is executed successfully
...
} catch (ExecutionException e) {
Throwable c = e.getCause();
log.error("Something happened running task", c);
// After task is aborted by exception
...
}
You can mutate the object that was passed-in during the task. For example:
final String[] mutable = new String[1];
Runnable r = new Runnable() {
public void run() {
mutable[0] = "howdy";
}
};
Future<String[]> f = executorService.submit(r, mutable);
String[] result = f.get();
System.out.println("result[0]: " + result[0]);
When I run this code it outputs:
result[0]: howdy
Related
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);
}
I have the following class
Class Results {
ResultA resultA;
ResultB resultB;
ResultC resultC;
}
The types of ResultA, ResultB, ResultC are different and cannot be fit under one class hierarchy.
I have a DAO which talks to db to get the above results
Class ResultDAO {
ResultA getResultA(/*takes non-zero argument list*/) {
}
ResultB getResultB(/*takes non-zero argument list*/) {
}
ResultC getResultC(/*takes non-zero argument list*/) {
}
}
I need to get the three results resultA, resultB, resultC by invoking the DAO methods. This needs to happen concurrently. I used an executor service and called the above three methods in different anonymous callables the following way. The reason for using callables over runnables although there is no return type is because ResultDAO throws checked exceptions and Runnable doesn't propagate checked exceptions whereas Callable does.
Result getResult() {
List<Callable<Void>> tasks = new ArrayList<>();
Results results = new Results();
tasks.add(new Callable<Void>() {
#Override
public Void call() throws Exception {
results.setResultA(resultDAO.getResultA(/*non-zero params*/));
return null;
}
});
tasks.add(new Callable<Void>() {
#Override
public Void call() throws Exception {
results.setResultB(resultDAO.getResultB(/*non-zero params*/));
return null;
}
});
tasks.add(new Callable<Void>() {
#Override
public Void call() throws Exception {
results.setResultC(resultDAO.getResultC(/*non-zero params*/));
return null;
}
});
List<Future<Void>> futures = executorService.invokeAll(tasks);
for(Future<Void> future: futures) {
future.get();
/*removing the exception handling part of future.get() for brevity*/
}
return result;
}
The above implementation clearly isn't good and signifies code smell. It's not easy and straight forward to make further modifications, write tests and maintaing the code. I have included only 3 result types in the question for simplicity. But there are more in the actual implementation which is why it's getting difficult to manage the code
I couldn't find the best practices for the above problem stated. Can anyone suggest a better implementation?
I have created a threadpool in Java with the help of ExecutorService and List of Futures.
I have created a RandomProcess class that implements Callable interface and overrides the call method
to perform certain operations.
It looks like this:
public class RandomProcess implements Callable<Integer> {
private Result result;
public RandomProcess(Result result) {
super();
this.result = result;
}
#Override
public Integer call() throws Exception {
//performSomeOps returns a Result that has certain values that I need
result = performSomeOps();
return 1;
}
I have this Result object in this class that is supposed to reflect the changes that were made
in the Randomprocess thread. unfortunately, the changes are not reflected when I return this Result.
public class Abc{
public Result check(){
Result result = new Result(true);
try {
ExecutorService exec = Executors.newFixedThreadPool(7);
List<Future<?>> futures = new ArrayList<Future<?>>(7);
for (Entity entity : randomListOfEntities) {
futures.add(exec.submit(new RandomProcess(result)));
}
for (Future<?> f : futures) {
f.get(); // wait for a process to complete
}
exec.shutdown();
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
Unable to figure out what the problem might be.
In Line result = performSomeOps();
you are not updating the value inside result that is being passed while submitting thread. You are just assigning new object at that line instead of changing the original object. You need to update the value inside result object(Something link result.setSomevalue() = performSomeOps().getSomeValue()) or pass your result object to performSomeOps(), and update result inside that method.
Need to Return "Result" as object from the "RandomProcess" Thread,Then Changes will be reflected.
public class RandomProcess implements Callable
{
private Result result;
public RandomProcess(Result result) {
super();
this.result = result;
}
#Override
public Result call() throws Exception {
result = performSomeOps();
return result;
}
}
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";
}
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);
}