Java Async wait for finish - java

Ho do i get my function to wait for being done with it's async task before returning the variable?
public boolean CheckOnline(){
OnlineAsyncTask onlinetsk = new OnlineAsyncTask();
onlinetsk.execute();
return Online;
}

You can call get() to wait for the async task to complete and retrieve the result.
However that defeats the purpose of an async task - it's no longer asynchronous. Consider redesigning your app so that you don't need to wait for a result. Instead e.g. use a callback interface to notify that the async task has finished and a result is available.

String str_result= new OnlineAsyncTask().execute().get();
This will make it wait till it returns the value

Related

Waiting for result using synchronized block causes App freeze

I have an object Task (see com.google.android.gms.tasks)
I need to wait till It has finished all operations before return result.
So I have tried to create a dummy object
final static Object lock=new Object();
to use as lock and I have added in the method
synchronized(lock){
lock.wait();
}
so that It doesn't return the value before task completion
calling lock.notifyAll in onSuccess() listener of the task (this listener is called when the task ends correctly).
But unfortunately the whole App freeze.
Why happens this?
How should I deal with Task completion?
(Note that Task isn't like AsyncTask)
There is a simple way to run a Task synchronously.
Tasks.await(yourTask);
But make sure this is called in a background thread.

Difference between using AsyncTask.get() and onPostExecute()

I've noticed on the documentation for AsyncTask here that you can use a method called get() to retrieve your result once the work on the thread is done. The documentation says that it
Waits if necessary for the computation to complete, and then retrieves its result.
Does that mean if I have this line of code:
List<Data> data = someAsyncTask.execute.get();
in the main UI thread, does it wait for the task to complete before executing any code after it? If so, this would render the use of AsyncTask useless. What am I missing here?
Is AsyntTask.get() an alternative to using onPostExecute() to return data to the main thread? If so, is it safe? Or is its use for something completely different?
If you call AsyncTask.get() and the task is not completed, then current thread will wait (and can be interrupted).
You right, calling this method in UI thread makes AsyncTask useless. But you can call it in another thread which need result of this task for further execution.

AsyncTask, handle result in onPostExecute vs get()

I would like to handle a return result from an AsyncTask outside of the class.
Is there any downside using, for example, Location loc = TheClass.execute().get();? Should I handle the result in onPostExecute inside the class instead?
The get() method is not well method for it, cause it stoped UI-thread
The only place where you can be assured that the operation you have started in doInBackground() has completed is the callback method onPostExecute(). So using a get() is not such a wise idea as far as AsyncTask is concerned.
get()
The purpose, of get(), is to block until the result is obtained. This
could be useful, for example, if you have multiple tasks, where one uses
another. One task could start another and call get() to wait for it to
finish before continuing with its own work.
onPostExecute (Result result)
Runs on the UI thread after doInBackground(Params...). The specified result is the value returned by doInBackground(Params...).
This method won't be invoked if the task was cancelled.
get() make you (current Thread) wait until the result come and onPostExecute did work Asynchronously and work like a call back when the background work has been completed.
http://developer.android.com/reference/android/os/AsyncTask.html#get()
public final Result get ()
Waits if necessary for the computation to complete, and then retrieves its result.

ExecutorService only run most recently added Callable

I have a single threaded executor service for fetching some data over the network.
As the user is typing in a search box I am enqueuing possible network tasks. What I want is to cancel all previous requests and only enqueue and immediately run the latest one.
My current approach is to override execute() and submit() methods and clear the queue before calling super.
Any thoughts on this?
Don't get it, why don't you save the Future returned on posting a callable to the service, and then cancel() the future if you don't want it to be executed.
e.g.
Future f1 = service.submit(some_task);
// later
f1.cancel(true); // will interrupt if running...
Cleaner IMO...

Java Wait for thread to finish

I have a thread downloading data and I want to wait until the download is finished before I load the data. Is there a standard way of doing this?
More Info:
I have a Download class that gets data from a URL (Serialized POJOs). Download is Runnable and Observable. It keeps track of the bytes downloaded and download size. I have a progress bar that displays the progress to the User. The GUI observes Download to update the progress bar.
When the POJO is downloaded I want to get it and move to the next step. Each step has to wait for the previous to finish. The problem is I cant think of a way to pause my application to wait for the download thread. Once the download is finished I want to call download.getObject() which will return the data as an object. I can then cast it and get on with the next download.
I have a helper class that manages the URLs for download and makes all of the calls to Download. This call will call getObject and do the casting. The Gui calls helper.getUser(). helper starts the thread running and I want it to 'know' when it is finished so it can return the casted object.
Any suggestions/examples? I am in the beginning stages of this design so I am willing to change it.
Update:
I followed http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html#get and used modal to block until the thread finished. The code was very messy and I don't like this approach. I will keep trying to find a 'clean' way to handle the workflow of the download processes.
Thread has a method that does that for you join which will block until the thread has finished executing.
You could use a CountDownLatch from the java.util.concurrent package. It is very useful when waiting for one or more threads to complete before continuing execution in the awaiting thread.
For example, waiting for three tasks to complete:
CountDownLatch latch = new CountDownLatch(3);
...
latch.await(); // Wait for countdown
The other thread(s) then each call latch.countDown() when complete with the their tasks. Once the countdown is complete, three in this example, the execution will continue.
Better alternatives to join() method have been evolved over a period of time.
ExecutorService.html#invokeAll is one alternative.
Executes the given tasks, returning a list of Futures holding their status and results when all complete. Future.isDone() is true for each element of the returned list.
Note that a completed task could have terminated either normally or by throwing an exception. The results of this method are undefined if the given collection is modified while this operation is in progress.
ForkJoinPool or Executors.html#newWorkStealingPool provides other alternatives to achieve the same purpose.
Example code snippet:
import java.util.concurrent.*;
import java.util.*;
public class InvokeAllDemo{
public InvokeAllDemo(){
System.out.println("creating service");
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
List<MyCallable> futureList = new ArrayList<MyCallable>();
for ( int i=0; i<10; i++){
MyCallable myCallable = new MyCallable((long)i);
futureList.add(myCallable);
}
System.out.println("Start");
try{
List<Future<Long>> futures = service.invokeAll(futureList);
}catch(Exception err){
err.printStackTrace();
}
System.out.println("Completed");
service.shutdown();
}
public static void main(String args[]){
InvokeAllDemo demo = new InvokeAllDemo();
}
class MyCallable implements Callable<Long>{
Long id = 0L;
public MyCallable(Long val){
this.id = val;
}
public Long call(){
// Add your business logic
return id;
}
}
}
You can use join() to wait for all threads to finish. Like below:
for (int i = 0; i < 10; i++)
{
Thread T1 = new Thread(new ThreadTest(i));
T1.start();
try {
T1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
SwingWorker has doInBackground() which you can use to perform a task. You have the option to invoke get() and wait for the download to complete or you can override the done() method which will be invoked on the event dispatch thread once the SwingWorker completes.
The Swingworker has advantages to your current approach in that it has many of the features you are looking for so there is no need to reinvent the wheel. You are able to use the getProgress() and setProgress() methods as an alternative to an observer on the runnable for download progress. The done() method as I stated above is called after the worker finishes executing and is performed on the EDT, this allows you load the data after the download has completed.
I imagine that you're calling your download in a background thread such as provided by a SwingWorker. If so, then simply call your next code sequentially in the same SwingWorker's doInBackground method.
Generally, when you want to wait for a thread to finish, you should call join() on it.
Any suggestions/examples? I followed SwingWorker... The code was very messy and I don't like this approach.
Instead of get(), which waits for completion, use process() and setProgress() to show intermediate results, as suggested in this simple example or this related example.
The join() method allows one thread to wait for the completion of another.However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.

Categories