Differences and examples of Runnable, Callable, Future, and FutureTask in Java

Source: Internet
Author: User

Java has several thread-related classes or interfaces, such as Runnable, Callable, Future, and FutureTask. They are also important concepts in Java, let's take a simple example below to learn the differences between them.

Runnable

Among them, Runnable should be the most familiar interface. It has only one run () function, which is used to write time-consuming operations in it,This function has no return value.. Then, you can use a Thread to execute the runnable to implement multithreading. After the Thread class calls the start () function, it executes the Runnable run () function. The Runnable statement is as follows:

public interface Runnable {    /**     * When an object implementing interface Runnable is used     * to create a thread, starting the thread causes the object's     * run method to be called in that separately executing     * thread.     * 

* * @see java.lang.Thread#run() */ public abstract void run();}

Callable

Callable and Runnable have similar functions. Callable has a call () function,However, the call () function has a return value.Runnable's run () function cannot return the result to the client program. The Callable statement is as follows:

public interface Callable
 
   {    /**     * Computes a result, or throws an exception if unable to do so.     *     * @return computed result     * @throws Exception if unable to compute a result     */    V call() throws Exception;}
 
As you can see, this is a generic interface, and the type returned by the call () function is the V type passed in by the client program.

Future

Executor is the scheduling container of Runnable and Callable,The Future is the execution result of a specific Runnable or Callable task.

Cancel,Check whether the operation is complete, obtain the result, and set the result.. The get method is blocked until the task returns results (about Future ). The Future statement is as follows:

/*** @see FutureTask * @see Executor * @since 1.5 * @author Doug Lea * @param 
 
   The result type returned by this Future's 
  get method */public interface Future
  
    {    /**     * Attempts to cancel execution of this task.  This attempt will     * fail if the task has already completed, has already been cancelled,     * or could not be cancelled for some other reason. If successful,     * and this task has not started when 
   cancel is called,     * this task should never run.  If the task has already started,     * then the 
   mayInterruptIfRunning parameter determines     * whether the thread executing this task should be interrupted in     * an attempt to stop the task.     *     */    boolean cancel(boolean mayInterruptIfRunning);    /**     * Returns 
   true if this task was cancelled before it completed     * normally.     */    boolean isCancelled();    /**     * Returns 
   true if this task completed.     *     */    boolean isDone();    /**     * Waits if necessary for the computation to complete, and then     * retrieves its result.     *     * @return the computed result     */    V get() throws InterruptedException, ExecutionException;    /**     * Waits if necessary for at most the given time for the computation     * to complete, and then retrieves its result, if available.     *     * @param timeout the maximum time to wait     * @param unit the time unit of the timeout argument     * @return the computed result     */    V get(long timeout, TimeUnit unit)        throws InterruptedException, ExecutionException, TimeoutException;}
  
 

FutureTask

FutureTask is a RunnableFuture RunnableFuture implements Runnbale and Futrue. These two interfaces,

public class FutureTask
 
   implements RunnableFuture
  
 
RunnableFuture

public interface RunnableFuture
 
   extends Runnable, Future
  
    {    /**     * Sets this Future to the result of its computation     * unless it has been cancelled.     */    void run();}
  
 

It can also encapsulate Runnable and Callable , Injected by the constructor.

    public FutureTask(Callable
 
   callable) {        if (callable == null)            throw new NullPointerException();        this.callable = callable;        this.state = NEW;       // ensure visibility of callable    }    public FutureTask(Runnable runnable, V result) {        this.callable = Executors.callable(runnable, result);        this.state = NEW;       // ensure visibility of callable    }
 
As you can see, Runnable injection is converted to the callable type by the Executors. Callable () function, that is, the FutureTask will eventually execute the Callable type task. The adaptation function is implemented as follows:

    public static 
 
   Callable
  
    callable(Runnable task, T result) {        if (task == null)            throw new NullPointerException();        return new RunnableAdapter
   
    (task, result);    }
   
  
 
RunnableAdapter

    /**     * A callable that runs given task and returns given result     */    static final class RunnableAdapter
 
   implements Callable
  
    {        final Runnable task;        final T result;        RunnableAdapter(Runnable task, T result) {            this.task = task;            this.result = result;        }        public T call() {            task.run();            return result;        }    }
  
 

Because FutureTask implements Runnable, it can be directly executed through Thread packaging, or submitted to ExecuteService for execution.

You can also directly obtain the execution result through the get () function, which will be blocked until the result is returned.Therefore, FutureTask is both a Future,

Runnable,Callable is encapsulated again (if Runnable is eventually converted to Callable), it is the combination of the two.


Simple Example

Package com. valid tive. java. concurrent. task; import java. util. concurrent. callable; import java. util. concurrent. executionException; import java. util. concurrent. executorService; import java. util. concurrent. executors; import java. util. concurrent. future; import java. util. concurrent. futureTask;/***** @ author mrsimple **/public class RunnableFutureTask {/*** ExecutorService */static ExecutorService mExecutor = Executors. newSingleThreadExecutor ();/***** @ param args */public static void main (String [] args) {runnableDemo (); futureDemo ();}/*** runnable, no return value */static void runnableDemo () {new Thread (new Runnable () {@ Overridepublic void run () {System. out. println ("runnable demo:" + fibc (20 ));}}). start ();}/*** in which Runnable implements the void run () method without returning values. Callable implements the V * call () method and can return execution results. Among them, Runnable can be submitted to the Thread for packaging *, directly starting a Thread for execution, while Callable is generally submitted to ExecuteService for execution. */Static void futureDemo () {try {/*** submit runnable without returning value. future has no data */Future
 Result = mExecutor. submit (new Runnable () {@overridepublic void run () {fibc (20) ;}}); System. out. println ("future result from runnable:" + result. get ();/*** submit Callable, with a return value. The return value can be obtained in future */Future
 
  
Result2 = mExecutor. submit (new Callable
  
   
() {@ Overridepublic Integer call () throws Exception {return fibc (20) ;}}); System. out. println ("future result from callable:" + result2.get ();/*** FutureTask is a RunnableFuture
   
    
That is, Runnbale and Futrue are implemented.
    
     
In addition, it can also encapsulate Runnable (actually converted to Callable) and Callable *
     
      
Therefore, it is generally a conformances. It can be executed directly through Thread packaging, or submitted to ExecuteService for execution *, and the execution result can be returned through v get, when the thread body is not completed, the main thread is blocked and waits, and the result is directly returned after the execution. */FutureTask
      
        FutureTask = new FutureTask
       
         (New Callable
        
          () {@ Overridepublic Integer call () throws Exception {return fibc (20) ;}}); // submit futureTaskmExecutor. submit (futureTask); System. out. println ("future result from futureTask:" + futureTask. get ();} catch (InterruptedException e) {e. printStackTrace ();} catch (ExecutionException e) {e. printStackTrace () ;}/ *** efficiency-based Fibonacci sequence, time-consuming operation ** @ param num * @ return */static int fibc (int num) {if (num = 0) {return 0;} if (num = 1) {return 1;} return fiber c (num-1) + fiber c (num-2 );}}
        
       
      
     
    
   
  
 

Output result

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.