The Java programmer must master the thread knowledge-callable and future

Source: Internet
Author: User

The reason for the emergence of callable and future

There are 2 ways to create threads, one is to inherit the thread directly, and the other is to implement the Runnable interface.
One drawback to all 2 of these approaches is that you cannot get the results of the execution after the task has been completed.
If you need to get the results of execution, you have to use shared variables or the way you use thread communication to achieve the effect, which is more troublesome.

Since the beginning of Java 1.5, callable and the future have been provided, through which the task execution results can be obtained after the task has been completed. Callable and future Introduction

The callable interface represents a piece of code that can be called and returns the result; The future interface represents an asynchronous task, which is the result of a task that has not yet been completed. So callable is used to produce results, and the future is used to get results.

The callable interface uses generics to define its return type. The Executors class provides some useful ways to perform tasks within a callable in a thread pool. Since the callable task is parallel (parallel is that the whole looks parallel, in fact there is only one thread executing at a point in time), we must wait for the result to be returned.
The Java.util.concurrent.Future object solves this problem for us. After the online pool submits the callable task, it returns a future object that can be used to know the status of the callable task and get the result of the callable return. The future provides a get () method so that we can wait for callable to end and get its execution results.

Callable and Runnable

Java.lang.Runnable, it is an interface that only declares a run () method in it:

 Public Interface Runnable {    publicabstractvoid  run ();}

Because the run () method returns a value of type void, no results can be returned after the task has been executed.

Callable is located under the Java.util.concurrent package, which is also an interface, in which only one method is declared, but this method is called call ():

 Public Interface Callable<v> {    /**     * Computes a result, or throws an exception if unable to does so.     *     @return  computed result     @throws  Exception If unable to compute a Result     *   /throws Exception;}    

As you can see, this is a generic interface, and the type that the call () function returns is the type of V passed in.

So how do you use callable?

Typically used in conjunction with Executorservice, the overloaded versions of several submit methods are declared in the Executorservice interface:

<T> future<t> Submit (callable<t> Task); <T> future<t> Submit (Runnable task, T result); Future <?> Submit (Runnable Task);

The parameter type in the first Submit method is callable.

For the time being only need to know that callable is generally used with the Executorservice, the specific use of the method is explained in the following.

In general we use the first Submit method and the third submit method, and the second submit method is seldom used.

Future

The future is to cancel the execution result of the specific runnable or callable task, whether the query is completed, and the result is obtained. If necessary, the result of the execution can be obtained through the Get method, which blocks until the task returns the result.

The future class is located under the Java.util.concurrent package, which is an interface:

 Public Interface Future<v> {    boolean Cancel (boolean  mayinterruptifrunning);     Boolean iscancelled ();     Boolean IsDone ();     throws interruptedexception, executionexception;    V Get (long  timeout, timeunit unit)        throws  interruptedexception, Executionexception, timeoutexception;}
5 methods are declared in the future interface, which in turn explains the function of each method:

The Cancel method is used to cancel the task and returns true if the Cancel task succeeds, or False if the cancel task fails. The parameter mayinterruptifrunning indicates whether a task that is executing but not completed is allowed to be canceled, and if set to true, it means that the task in the process of execution can be canceled. If the task is completed, whether mayinterruptifrunning is true or FALSE, this method will definitely return false, that is, if canceling the completed task returns false, or if the task is executing, Returns True if the mayinterruptifrunning is set to true, or False if the mayinterruptifrunning is set to false, or if the task has not been executed, Returns true regardless of whether mayinterruptifrunning is true or false.

The IsCancelled method indicates whether the task was canceled successfully and returns true if the task was canceled successfully before it was properly completed.

The Isdone method indicates whether the task has completed and returns true if the task completes;

The Get () method is used to get the result of the execution, this method will be blocked, will wait until the task is completed before returning;

Get (long timeout, timeunit unit) is used to get the execution result, and if the result is not obtained within the specified time, NULL is returned directly.

This means that the future offers three functions:

1) Determine whether the task is completed;

2) ability to interrupt tasks;

3) Ability to get task execution results.

Because the future is just an interface, it is not directly used to create objects, so there is the following futuretask.

The Futuretaskfuturetask implements the Runnablefuture interface, which is defined as follows:
 Public Interface extends Runnable, future<v> {      void  run ();  }  

We can see that this interface implements the Runnable and the future interface, and the concrete implementation of the interface is implemented by Futuretask. The two construction methods of this class are as follows:

 Public Futuretask (callable<v> callable) {          ifnull)              throw  New  nullpointerexception ();           New Sync (callable);      }        Public Futuretask (Runnable Runnable, V result) {          new  Sync (executors.callable (Runnable, result));      }  

As above, two constructors are provided, one with callable as parameter and the other with runnable as parameter. The association between these classes is very flexible in the way the task is modeled, allowing you to write the task callable based on the Futuretask runnable feature (because it implements the Runnable interface). It is then encapsulated into a futuretask that is dispatched by the performer and can be canceled if necessary.

Futuretask can be dispatched by the performer, which is critical. The method it provides is basically a combination of the future and the Runnable interface: Get (), Cancel, IsDone (), iscancelled (), and run (), and the Run () method is usually called by the performer, and we basically don't need to call it directly.

An example of a futuretask
 Public classMycallableImplementsCallable<string> {      Private LongWaitTime;  PublicMycallable (intTimeinmillis) {            This. waittime=Timeinmillis; } @Override PublicString Call ()throwsException {thread.sleep (waitTime); //return the thread name executing this callable task        returnThread.CurrentThread (). GetName (); }  } 
 Public classFuturetaskexample { Public Static voidMain (string[] args) {mycallable callable1=NewMycallable (1000);//the task to performMycallable Callable2 =NewMycallable (2000); Futuretask<String> FutureTask1 =NewFuturetask<string> (CALLABLE1);//encapsulates callable-written tasks into a Futuretask object that is dispatched by the performerFuturetask<string> FutureTask2 =NewFuturetask<string>(Callable2); Executorservice Executor= Executors.newfixedthreadpool (2);//Create a thread pool and return Executorservice instancesExecutor.execute (FUTURETASK1);//Perform TasksExecutor.execute (FUTURETASK2);  while(true) {              Try {                  if(Futuretask1.isdone () && futuretask2.isdone ()) {//two tasks are completeSystem.out.println ("Done");                          Executor.shutdown (); //turn off the thread pool and services                    return; }                  if(!futuretask1.isdone ()) {//Task 1 is not completed and will wait until the task is completedSystem.out.println ("FutureTask1 output=" +futuretask1.get ()); } System.out.println ("Waiting for FutureTask2 to complete"); String s= Futuretask2.get (200L, Timeunit.milliseconds); if(s! =NULL) {System.out.println ("FutureTask2 output=" +s); }              } Catch(Interruptedexception |executionexception e)              {E.printstacktrace (); }Catch(TimeoutException e) {// do nothing            }          }      }  }  

After running the program as above, you can see that there is no output for a period of time because the Get () method waits for the task to finish before outputting the content.

The output results are as follows:
FutureTask1 output=pool-1-thread-1   for for  for- FutureTask2 to CompleteFutureTask2 output=pool-1-thread-2-Done  

Threading Knowledge-callable and future that Java programmers must master

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.