Java 5.0 在java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口。
Callable 接口类似于Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是Runnable 不会返回结果,并且无法抛出经过检查的异常。
Callable接口示例如下:
public class TestCallable { public static void main(String[] args){ CallableDemo callableDemo = new CallableDemo(); //执行Callable需要有FutureTask支持,用于接收运算结果 FutureTask<Integer> futureTask = new FutureTask<>(callableDemo); new Thread(futureTask).start(); try { //接收线程运算后结果 Integer sum = futureTask.get(); System.out.println(sum); //futureTask.get();执行完才能打印横线,说明 System.out.println("--------------------------------------"); }catch (Exception e) { e.printStackTrace(); } } } class CallableDemo implements Callable<Integer>{ @Override public Integer call() throws Exception { int sum=0; for (int i=0;i<=100;i++){ System.out.println(i); sum+=i; } return sum; } }
jdk1.8下可以使用lambda表达式,修改如下:
FutureTask<Integer> futureTask = new FutureTask<>(()->{ int sum=0; for (int i=0;i<=100;i++){ System.out.println(i); sum+=i; } return sum; }); new Thread(futureTask).start();
Callable 需要依赖FutureTask ,FutureTask 也可以用作闭锁。
如下图所示,只有获取到结果后才会打印横线:
FutureTask拥有方法如下:
其实现了RunnableFuture接口:
public class FutureTask<V> implements RunnableFuture<V> { //... }
其中RunnableFuture接口又继承自Runnable和Future接口:
// 一个Future 就是一个Runnable,run方法的成功执行会使得Future结束并访问结果 public interface RunnableFuture<V> extends Runnable, Future<V> { //将此未来设置为其计算结果,除非已取消 void run(); }
Future是什么,有什么用?
查看其javadoc如下:
/** * A {@code Future} represents the result of an asynchronous * computation. Methods are provided to check if the computation is * complete, to wait for its completion, and to retrieve the result of * the computation. The result can only be retrieved using method * {@code get} when the computation has completed, blocking if * necessary until it is ready. Cancellation is performed by the * {@code cancel} method. Additional methods are provided to * determine if the task completed normally or was cancelled. Once a * computation has completed, the computation cannot be cancelled. * If you would like to use a {@code Future} for the sake * of cancellability but not provide a usable result, you can * declare types of the form {@code Future<?>} and * return {@code null} as a result of the underlying task.