Java Wait for thread to finish

JavaMultithreadingSwingDownloadWait

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

Thread has a method that does that for you join which will block until the thread has finished executing.

Solution 2 - Java

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.

Solution 3 - Java

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:

Solution 4 - Java

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

Solution 5 - Java

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.

Solution 6 - Java

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.

Solution 7 - Java

Generally, when you want to wait for a thread to finish, you should call join() on it.

Solution 8 - Java

>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.

Solution 9 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAllanView Question on Stackoverflow
Solution 1 - JavaunholysamplerView Answer on Stackoverflow
Solution 2 - JavapermagnussonView Answer on Stackoverflow
Solution 3 - JavaRavindra babuView Answer on Stackoverflow
Solution 4 - JavaDeepakView Answer on Stackoverflow
Solution 5 - JavatstevensView Answer on Stackoverflow
Solution 6 - JavaHovercraft Full Of EelsView Answer on Stackoverflow
Solution 7 - JavabiziclopView Answer on Stackoverflow
Solution 8 - JavatrashgodView Answer on Stackoverflow
Solution 9 - JavaJatin MandankaView Answer on Stackoverflow