I've got a inner class in my class doing some asynchronous processing and setting value on parent class. Ex :
class Myclass{
String test;
public getTestValueFromMyClass(){
//this starts asynchronous processing on my inner class
}
//inner class
class InnerClass extends TimerTask{
//doing something asynchronously, when this process is done
test = "somevalue";
}
}
Now here is the problem from Runner class :
class Runner{
public static void main(String[] args){
Myclass instance = new Myclass();
//This is always null because runner class doesn't wait for Inner class to
//complete asynchronous processing and to set test value
System.out.println(instance.getTestValueFromMyClass());
}
}
How do I get around this?
Others have suggested similar ideas but I'd use a single thread pool with a Callable.
Your class that is doing the asynchronous processing should implement Callable which will return the computed value. In this example it returns a String but it could also return your own object with more information.
public class MyClass implements Callable<String> {
public String call() {
//doing something asynchronously, when this process is done
return "somevalue";
}
}
Your Runner class would then create a thread pool, fire off the asynchronous task in the background, and then later wait for it to finish. When you submit a Callable job to the thread-pool, you get a Future class back which can be used to wait for the asynchronous job to finish and to get its return value.
public class Runner{
public static void main(String[] args) {
// you can use newFixedThreadPool(...) if you need to submit multiple
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// you could store this future in a collection if you have multiple
Future<String> future = threadPool.submit(new MyClass());
// after submitting the final job, we _must_ shutdown the pool
threadPool.shutdown();
// do other stuff in the "foreground" while MyClass runs in the background
// wait for the background task to complete and gets its return value
// this can throw an exception if the call() method threw
String value = future.get();
System.out.println(value);
}
}
Evidently, you have to make getTestValueFromMyClass to wait for InnerClass execution. This can be done with some synchronization facility (Semaphore, CountdownLatch, BlockingQueue...). But most straightforward is to use java.util.concurrent.ScheduledThreadPoolExecutor instead of java.util.Timer. Its method schedule(Callable<V> callable, long delay, TimeUnit unit) returns Future, and Future.get() waits for and returns the computed value.
One very simple mechanism is to use a BlockingQueue to communicate between your threads. Here I am creating the queue in the thread class but it could just as easily be created in the caller and passed to the thread.
public class Runner {
static class MyClass implements Runnable {
// Thread will post to this queue when it completes.
BlockingQueue q = new ArrayBlockingQueue(1);
// Call to wait for the post.
public void waitForFinish() throws InterruptedException {
// Just take! This will wait until something gets posted.
q.take();
}
#Override
public void run() {
try {
// Just wait ten seconds.
Thread.sleep(10000);
} catch (InterruptedException ex) {
// Just exit when interrupted.
} finally {
try {
// Signal finished.
q.put("Done");
} catch (InterruptedException ex) {
// Just exit when interrupted.
}
}
}
}
public static void main(String[] args) throws InterruptedException {
// Make my instance.
MyClass instance = new MyClass();
// Fire it off.
new Thread(instance).start();
// Wait for it to finish.
instance.waitForFinish();
// All done.
System.out.println("Finished");
}
}
You could use a handler and post a message when processing is done!
class Myclass{
// pre initialize thread pool
private static ExecutorService executor = Executors.newFixedThreadPool( 5 );
private String test;
public String getTestValueFromMyClass() throws Exception {
// start asynchronous calculations
Future<String> resultHandler =
executor.submit( new Callable<String>() {
#Override
public String call() throws Exception {
return "Asynchronously calculated result";
}
} );
// do something in current thread
// ...
// wait until asynchronous task ends, get result
// and assign it to instance variable
this.test = resultHandler.get();
return test; // returns string "Asynchronously calculated result"
}
}
Related
i've been working for a while for a simple Maze project, and i got to the point where i need to use the Callable interface as a thread. After implementing and running, i've noticed that while the callable class runs in the background, i cant seem to work anything else on the background, such as to the an input.
i made a little project the emphasize the problem, see that while the callable class works for 10 seconds, i cant take any input in the meanwhile.
here is the code:
Main class
public class Main {
static ExecutorService service = null;
static Future<String> task = null;
public static void main(final String[] argv) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("please enter a command");
String string = in.readLine();
while (!string.equals("exit")) {
if (!string.equals("command")) {
System.out.println("command not found");
} else {
service = Executors.newFixedThreadPool(1);
task = service.submit(new Foo());
try {
final String str;
// waits the 10 seconds for the Callable.call to finish.
str = task.get(); // this raises ExecutionException if
// thread dies
System.out.println(str);
service.shutdownNow();
} catch (final InterruptedException ex) {
ex.printStackTrace();
} catch (final ExecutionException ex) {
ex.printStackTrace();
}
}
string = in.readLine();
}
//
}
}
the callable class:
class Foo implements Callable<String> {
#Override
public String call() {
try {
// sleep for 10 seconds
Thread.sleep(10 * 1000);
} catch (final InterruptedException ex) {
ex.printStackTrace();
}
return ("Hello, World!");
}
}
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable)
If you would like to immediately block waiting for a task, you can use constructions of the form result = exec.submit(aCallable).get();
That is exactly what you are doing (block the main thread waiting for a task)
The problem is str = task.get();.
According to the JavaDoc for Future#get() (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#get%28%29):
Waits if necessary for the computation to complete, and then retrieves its result.
If you want the result from your Callable, you have to wait until it's finished.
Callable doesn't do anything in and of itself. It is just a convention interface. To make callable asynchronous, you need to run it in an executor. See https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6 for instance.
i've noticed that while the callable class runs in the background, i cant seem to work anything else on the background
...discussion, ... problem explained...
it seems pointless to use this interface now.
I don't really know what you were trying to do, but the entire point of ExecutorService and Callable is to perform tasks in the background.
But what does "in the background" mean? It means, that while the new thread is off performing some task, the thread that submitted the task can do something else.
It looks like this:
final ExecutorService executorService = Executors.newFixedThreadPool(NUM_THREADS);
ReturnType doSomethingInTheBackground() {
// create the task object
Callable<ReturnType> task = () -> doSomething();
// submit the task object
Future<ReturnType> future = executorService.submit(task);
doSomethingElse();
// wait for the result.
return future.get();
}
private ReturnType doSomething() { ... }
private void doSomethingElse() { ... }
The doSomethingElse() call is what makes it all worthwhile. If the calling thread doesn't have anything else to do except wait for the result (i.e., call future.get()), then you were right: There would be no point in using more than one thread. It would be simpler for the calling thread to just do the task itself.
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";
}
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.
Below is the source code of the class.
I wanted to verify how does shutdownNow() works for not submitted task. Problem I am getting in below code is shutdownNow() return List<FutureTask> and not List<Runnable> which I have submitted List<Runnable> containing submitted instance of PrimeProducer .
In Below program I wanted to get the tasks which where not executed and their state so that I can reschedule them later. name() represents just state that I want to store.
So I am not able to convert to submitted Task.
class PrimeProducer implements Runnable {
private final SynchronousQueue<BigInteger> queue;
PrimeProducer(SynchronousQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
System.out.println("Safe Exit");
Thread.currentThread().interrupt();
}
}
public String name() {
return "PrimeProducer";
}
public static void main(String[] args) throws InterruptedException,
ExecutionException {
PrimeProducer primeProducer = new PrimeProducer(
new SynchronousQueue<BigInteger>());//SynchronousQueue just to ensure it put is blocking
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(primeProducer);
executorService.submit(primeProducer);
List<Runnable> list = executorService.shutdownNow();
//PrimeProducer producer = (PrimeProducer) list.get(0);// Class Cast
// Exception
FutureTask<PrimeProducer> futureTask = (FutureTask<PrimeProducer>) list
.get(0);
System.out.println(futureTask.isDone());//Prints false
futureTask.get().name();//futureTask-->PrimeProducer get() hangs.
}
}
Problematic Lines
//PrimeProducer producer = (PrimeProducer) list.get(0);// Class Cast
// Exception
FutureTask<PrimeProducer> futureTask = (FutureTask<PrimeProducer>) list
.get(0);
futureTask.get().name();//futureTask-->PrimeProducer get() hangs.
Try "execute" instead of "submit".
This behavior happens because there is difference between how execute and submit handles task that are submitted.
execute method directly uses Runnable command which is passed to it where as submit create RunnableFuture and call execute
RunnableFuture<Object> ftask = newTaskFor(task, null);
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);
}