The callable interface represents a piece of code that can invoke and return the result; The future interface represents the asynchronous task, which is the future result of a task that has not yet been completed. So callable is used to produce results, future are used to obtain results.
Java 5 introduces the Java.util.concurrent.Callable interface in the concurrency package, which is similar to the Runnable interface, but it can return an object or throw an exception.
The callable interface uses generics to define its return type. The Executors class provides some useful ways to perform tasks within callable in a thread pool. Because the callable task is parallel (parallelism is that the whole appears to be parallel, in fact only one thread is executing at a point in time), we have to wait for the result that it returns.
The Java.util.concurrent.Future object solved the problem for us. The online pool submits the callable task and returns a future object that can be used to know the status of the callable task and the results of the execution callable return. Future provides a get () method that allows us to wait for the callable to finish and get its execution results.
The source code of the callable interface is as follows:
Public interface Callable<v> {
V call () throws Exception;//calculation result
}
The source code of the Future interface is as follows:
Public interface Future<v> {
boolean mayinterruptifrunning);//attempt to cancel execution of this task
Boolean iscancelled (); Returns True
Boolean isdone () If the task is canceled before it is properly completed; Returns True
V get () throws Interruptedexception, executionexception if necessary, wait for the calculation to complete, and then obtain the result if the task is completed.
If necessary, wait up to the time given for the calculation to complete, and obtain its results if the results are available.
V Get (long timeout, timeunit) throws Interruptedexception, Executionexception, timeoutexception;
}
Future is used to represent the results of an asynchronous computation. Its implementation class is Futuretask.
If you do not want to block the main thread, and want to get the results of the implementation of the branch, use Futuretask
The Futuretask implements the Runnablefuture interface, which is defined as follows:
Public interface runnablefuture<v> extends Runnable, future<v> {
void Run ();
}
You can see that this interface implements the runnable and future interfaces, and the concrete implementations of the interfaces are implemented by Futuretask. The two construction methods for this class are as follows:
Public Futuretask (callable<v> callable) {
if (callable = = null)
throw new NullPointerException ();
sync = new sync (callable);
}
Public Futuretask (Runnable Runnable, V result) {
sync = new sync (executors.callable (Runnable, result));
}
Two constructors are provided, one with callable as arguments and the other with runnable as arguments. The association between these classes is very flexible in the way the task is modeled, allowing you to Futuretask runnable features (because it implements the Runnable interface) and write the task as callable, It is then encapsulated into a futuretask that is scheduled by the performer and can be canceled if necessary.
It is critical that Futuretask be scheduled by the performer. The approach it provides is basically a combination of the future and Runnable interfaces: Get (), Cancel, Isdone (), iscancelled (), and run (), and the Run () method is usually invoked by the performer, and we basically don't need to call it directly.
Here's a futuretask example, as follows:
public class Mycallable implements callable<string> {
private long waittime;
Public mycallable (int timeinmillis) {
this.waittime=timeinmillis;
}
@Override public
String call () throws Exception {
thread.sleep (waittime);
Return to the thread name executing this callable task return
Thread.CurrentThread (). GetName ();
}
public class Futuretaskexample {public static void main (string[] args) {mycallable callable1 = new Mycallab Le (1000);
The task to perform mycallable callable2 = new Mycallable (2000); futuretask<string> FutureTask1 = new futuretask<string> (CALLABLE1); Encapsulates a callable-written task to a Futuretask object scheduled by the performer futuretask<string> FutureTask2 = new Futuretask<string> (callable
2); Executorservice executor = Executors.newfixedthreadpool (2); Creates a thread pool and returns the Executorservice instance Executor.execute (FUTURETASK1);
Executor.execute (FUTURETASK2) for the implementation of the Mission;
while (true) {try {if (Futuretask1.isdone () && Futuretask2.isdone ()) {//two tasks are complete
System.out.println ("Done"); Executor.shutdown ();
Close the thread pool and service return; } if (!futuretask1.isdone ()) {//Task 1 is not completed and will wait until the task is completed System.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 as a program, you can see no output for a period of time because the Get () method waits for the task to complete before outputting the content.
The output results are as follows:
1 2 3 4 5 6 7 8 |
FutureTask1 output=pool-1-thread-1 waiting for FutureTask2 to complete waiting for FutureTask2 to complete waiting for Fut UreTask2 to complete waiting for FutureTask2 to complete waiting for FutureTask2 to complete FutureTask2 Ead-2 Done |