Callable, Future, and FutureTask
In Java, besides the Runnable interface, there are also Callable interfaces.
The difference between the two is that the latter can return values, which are generally used for time-consuming computing.
The Runnable interface is used in many threads. Generally, it can be used as the thread execution body. Callable is generally used in combination with FutureTask.
The source code of the Callable interface is as follows:
/*** A task that returns a result and may throw an exception. * Implementors define a single method with no arguments called * {@ code call }. * A task with a returned value may throw an exception. **
The {@ code Callable} interface is similar to {@ link * java. lang. runnable}, in that both are designed for classes whose * instances are potentially executed by another thread. A * {@ code Runnable}, however, does not return a result and cannot * throw a checked exception. * The Callable interface is similar to the Runnable interface and is a class instance designed for execution by other threads. * However, the Runnable interface does not return results and cannot throw a checked exception. **
The {@ link Executors} class contains utility methods to * convert from other common forms to {@ code Callable} classes. * The Executors class contains helper classes that convert other common forms into Callable classes. ** @ See Executor * @ since 1.5 * @ author Doug Lea * @ param The result type of method {@ code call} */@ FunctionalInterface 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 ;}
The Future interface is used to represent the results of asynchronous computing. This interface includes methods for checking whether the computing is complete, waiting for the computing to end, and obtaining the computing results.
Get () can obtain the calculation result. The current thread is blocked until the calculation is complete. Computing can be canceled.
FutureTask implements the RunnableFuture interface:
public class FutureTask
implements RunnableFuture
{
The RunnableFuture interface inherits from Runnable and Future:
public interface RunnableFuture
extends Runnable, Future
{
FutureTask indicates the asynchronous computing that can be canceled as the implementation of the Future interface. FutureTask can wrap the Runnable interface,
In addition, the Runnable interface can be submitted to the Executor for execution.
Run the following code to test it:
import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.Future;import java.util.concurrent.FutureTask;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class Main { public static void main(String[] args) throws InterruptedException, ExecutionException { Runnable runnable = new Runnable() { @Override public void run() { System.out.println(runnable running); } }; Callable
callable = new Callable
() { @Override public Integer call() throws Exception { System.out.println(callable running); return 123; } }; Callable
callable1 = new Callable
() { @Override public Integer call() throws Exception { System.out.println(callable1 running); return 123; } }; //runnable Thread thread1 = new Thread(runnable); thread1.start(); //callable FutureTask
future = new FutureTask
(callable); Thread thread2 = new Thread(future); thread2.start(); System.out.println(future is done? +future.isDone()); //future.cancel(false); Thread.sleep(1000); System.out.println(future result: +future.get()); ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue
()); executor.execute(runnable); FutureTask
future1 = new FutureTask
(callable1); executor.execute(future1); FutureTask
ft = new FutureTask
(runnable, aaaaa); Thread thread3 = new Thread(ft); thread3.start(); while(!ft.isDone()){ Thread.sleep(1000); } System.out.println(future runnable result: +ft.get()); Future
futureTask = executor.submit(callable); while(!futureTask.isDone()){ Thread.sleep(1000); } System.out.println(futureTask result: +futureTask.get()); executor.shutdown(); }}
Output result:
Runnable running
Future is done? False
Callable running
Future result: 123
Runnable running
Callable1 running
Runnable running
Future runnable result: aaaaa
Callable running
FutureTask result: 123