in the previous article we talked about the 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.
Today we will discuss the use of the callable, future, and futuretask three classes. The following is the directory outline for this article:
I. Callable and runnable
Two. Future
Three. Futuretask
Four. Using the example
I. Callable and runnable
There are several differences between callable and runnable:
(1) The method prescribed by callable is call (), and the method specified by runnable is run ().
(2) callable can return a value after a task is executed, and Runnable's task cannot return a value.
(3) The call () method throws an exception, and the run () method cannot throw an exception.
(4) Running callable task can get a future object,
Let's talk about Java.lang.Runnable, it's an interface that only declares a run () method in it:
Public interface Runnable {public abstract void 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 * /V call () throws Exceptio n;}
Instance:
public class Callabletest {//Create a calculation task, return the cumulative result, the constructor parameter is the upper bound static class Sumcaller implements Callable<long> {private Integer count;public sumcaller (integer count) {this.count = count;} Public Long Call () throws Exception {Long sum = 0;for (int i = 0; i < count; i++) {sum + = i;} return sum;}} private static Integer COUNT = 1000000000;public static void Main (string[] args) throws Interruptedexception,executionexc eption {Sumcaller caller = new Sumcaller (COUNT); futuretask<long> task = new futuretask<long> (caller); Thread thread = new thread (Task); Thread.Start (); Long sum = Task.get (); System.out.println ("Sum from 1 to" + COUNT + "result =" + sum);}}
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.
two. 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 represents the result of an asynchronous calculation. It provides a way to check whether the calculation is complete, to wait for the completion of the calculation, and to retrieve the results of the calculation.
The future object allows you to understand task execution, cancel the execution of a task, and get the results of a task execution.
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 (); V get () throws Interruptedexception, Executionexception; V get (long timeout, timeunit unit) throws Interruptedexception, Executionexception, TimeoutException;}
Futuretask is designed to compensate for the lack of thread, which allows the programmer to know exactly when a thread is executing and to get the results returned after the thread has finished executing (if necessary).
Futuretask is an asynchronous computational task that can be canceled . Its calculation is achieved through callable, which is equivalent to the runnable that can carry the result, and has three states: Wait, run, and finish. Completion includes all calculations ending in any way, including normal ends, cancellations, and exceptions.
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.
three. Futuretask
Let's take a look at the implementation of Futuretask:
public class Futuretask<v> implements Runnablefuture<v>
The Futuretask class implements the Runnablefuture interface, and we look at the implementation of the Runnablefuture interface:
Public interface runnablefuture<v> extends Runnable, future<v> { void run ();
It can be seen that runnablefuture inherits the Runnable interface and the future interface, and Futuretask implements the Runnablefuture interface. So it can be executed as runnable by thread, and can get callable return value as future.
The Futuretask provides 2 constructors:
Public Futuretask (callable<v> callable) {}public futuretask (Runnable Runnable, V result) {}
In fact, Futuretask is a unique implementation class for the future interface.
Four. Using the example
1. Using callable+future to get execution results
public class Test {public static void main (string[] args) {Executorservice executor = Executors.newcachedthrea Dpool (); Task task = new Task (); future<integer> result = Executor.submit (Task); Executor.shutdown (); try {thread.sleep (1000); } catch (Interruptedexception E1) {e1.printstacktrace (); } System.out.println ("Main thread is performing tasks"); try {System.out.println ("task Run Result" +result.get ()); } catch (Interruptedexception e) {e.printstacktrace (); } catch (Executionexception e) {e.printstacktrace (); } System.out.println ("All Tasks Completed"); }}class Task implements callable<integer>{@Override public Integer call () throws Exception {SYSTEM.O UT.PRINTLN ("Child threads are being computed"); Thread.Sleep (3000); int sum = 0; for (int i=0;i<100;i++) sum + = i; return sum; }}
Execution Result:
The child thread performs the task in the main thread of the calculation 4950 all tasks are completed
2. Using Callable+futuretask to get execution results
public class Test {public static void main (string[] args) {//First way executorservice executor = executors . Newcachedthreadpool (); Task task = new Task (); futuretask<integer> futuretask = new futuretask<integer> (Task); Executor.submit (Futuretask); Executor.shutdown (); In the second way, note that this is similar to the first method, except that one is using Executorservice, and one is using the thread/*task task = new Task (); futuretask<integer> futuretask = new futuretask<integer> (Task); Thread thread = new Thread (futuretask); Thread.Start (); */try {thread.sleep (1000); } catch (Interruptedexception E1) {e1.printstacktrace (); } System.out.println ("Main thread is performing tasks"); try {System.out.println ("task Run Result" +futuretask.get ()); } catch (Interruptedexception e) {e.printstacktrace (); } catch (Executionexception e) {e.printstacktrAce (); } System.out.println ("All Tasks Completed"); }}class Task implements callable<integer>{@Override public Integer call () throws Exception {SYSTEM.O UT.PRINTLN ("Child threads are being computed"); Thread.Sleep (3000); int sum = 0; for (int i=0;i<100;i++) sum + = i; return sum; }}
If you use the future for the sake of cancellation and do not provide the available results, you can declare the Future<?> form type and return null as the result of the underlying task.
Package Test;import Java.util.random;import Java.util.concurrent.callable;import Java.util.concurrent.executionexception;import java.util.concurrent.futuretask;/** * * @author Administrator * */@ Suppresswarnings ("All") public class Futuretaskdemo {public static void main (string[] args) {// Initializes a callable object and Futuretask object callable Paccount = new Privateaccount (); Futuretask futuretask = new Futuretask (paccount);//Use Futuretask to create a thread for threads paccountthread = new Thread (futuretask); System.out.println ("Futuretask thread starts now, startup time:" + system.nanotime ());p Accountthread.start (); System.out.println ("Main thread begins to perform other tasks");//Get total amount from other accounts int totalmoney = new Random (). Nextint (100000); System.out.println ("Now your total amount in other accounts is" + Totalmoney); System.out.println ("Wait for the total amount of the private account to be counted ...");//test the background of the calculation thread is complete, if not completed wait while (!futuretask.isdone ()) {try {thread.sleep ( 500); System.out.println ("Private account calculation not completed continue waiting ..."); catch (Interruptedexception e) {e.printstacktrace ();}} System.out.println ("Futuretask thread is calculated, this time is" + system.nanotime ()); Integer PrivaTeaccountmoney = null;try {Privateaccountmoney = (Integer) futuretask.get ();} catch (Interruptedexception e) { E.printstacktrace ();} catch (Executionexception e) {e.printstacktrace ();} System.out.println ("Your current total amount is:" + Totalmoney + privateaccountmoney.intvalue ());}} @SuppressWarnings ("All") class Privateaccount implements callable {Integer Totalmoney; @Overridepublic Object Call () Throws Exception {thread.sleep; Totalmoney = new Integer (new Random (). Nextint (10000)); System.out.println ("You currently have" + Totalmoney + "in your private Account"); return Totalmoney;}}
Summarize:
Futuretask is used for time-consuming computations, and the main thread can get results after completing its own tasks .
when using runnable alone :
Unable to get return value
when using callable alone :
cannot be used with new thread approached (Runnable R), only Executorservice
The thread class only supports runnable
Futuretask:
Realize the Runnable and future, so take into account both advantages
You can use Executorservice, or you can use the thread
If there are any shortcomings please understand, and welcome criticism.
This paper draws on:
Http://www.cnblogs.com/dolphin0520/p/3949310.html
Crazy Java Learning Note (callable)-----------, future, and Futuretask