Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good way to use java.util.concurrent.FutureTask?

First of all, I must say that I am quite new to the API java.util.concurrent, so maybe what I am doing is completely wrong.

What do I want to do?

I have a Java application that basically runs 2 separate processing (called myFirstProcess, mySecondProcess), but these processing must be run at the same time.

So, I tried to do that:

public void startMyApplication() {     ExecutorService executor = Executors.newFixedThreadPool(2);     FutureTask<Object> futureOne = new FutureTask<Object>(myFirstProcess);     FutureTask<Object> futureTwo = new FutureTask<Object>(mySecondProcess);     executor.execute(futureOne);     executor.execute(futureTwo);     while (!(futureOne.isDone() && futureTwo.isDone())) {         try {             // I wait until both processes are finished.             Thread.sleep(1000);         } catch (InterruptedException e) {             e.printStackTrace();         }     }     logger.info("Processing finished");     executor.shutdown();     // Do some processing on results     ... } 

myFirstProcess and mySecondProcess are classes that implements Callable<Object>, and where all their processing is made in the call() method.

It is working quite well but I am not sure that it is the correct way to do that. Is a good way to do what I want? If not, can you give me some hints to enhance my code (and still keep it as simple as possible).

like image 581
Romain Linsolas Avatar asked Feb 11 '09 11:02

Romain Linsolas


People also ask

What is the use of FutureTask in Java?

A FutureTask can be used to wrap a Callable or Runnable object. Because FutureTask implements Runnable , a FutureTask can be submitted to an Executor for execution. In addition to serving as a standalone class, this class provides protected functionality that may be useful when creating customized task classes.

What's the difference between Future and FutureTask in Java?

Future is a base interface and defines the abstraction of an object which promises results to be available in the future while FutureTask is an implementation of the Future interface.

What is Java Util Concurrent package?

util. concurrent package. This package has a set of classes and interfaces that helps in developing concurrent applications (multithreading) in java. Before this package, one needs to make the utility classes of their need on their own.

What is Java Util Concurrent Future?

util. concurrent. Future , represents the result of an asynchronous computation. When the asynchronous task is created, a Java Future object is returned. This Future object functions as a handle to the result of the asynchronous task.


2 Answers

You'd be better off using the get() method.

futureOne.get(); futureTwo.get(); 

Both of which wait for notification from the thread that it finished processing, this saves you the busy-wait-with-timer you are now using which is not efficient nor elegant.

As a bonus, you have the API get(long timeout, TimeUnit unit) which allows you to define a maximum time for the thread to sleep and wait for a response, and otherwise continues running.

See the Java API for more info.

like image 102
Yuval Adam Avatar answered Sep 21 '22 11:09

Yuval Adam


The uses of FutureTask above are tolerable, but definitely not idiomatic. You're actually wrapping an extra FutureTask around the one you submitted to the ExecutorService. Your FutureTask is treated as a Runnable by the ExecutorService. Internally, it wraps your FutureTask-as-Runnable in a new FutureTask and returns it to you as a Future<?>.

Instead, you should submit your Callable<Object> instances to a CompletionService. You drop two Callables in via submit(Callable<V>), then turn around and call CompletionService#take() twice (once for each submitted Callable). Those calls will block until one and then the other submitted tasks are complete.

Given that you already have an Executor in hand, construct a new ExecutorCompletionService around it and drop your tasks in there. Don't spin and sleep waiting; CompletionService#take() will block until either one of your tasks are complete (either finished running or canceled) or the thread waiting on take() is interrupted.

like image 31
seh Avatar answered Sep 22 '22 11:09

seh