目录
一、背景
二、Callable
三、Future
四、FutureTask
五、demo
一、背景
之前我们学习过线程的创建方法
继承继承Thread
实现Runnable接口
但是这两种方式都无法获取执行结果
而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果
接下来,我们来学习一下
二、Callable
先看一下源码
public interface Callable<V> {V call() throws Exception;
}
Callable是一个接口,在它里面声明了一个方法call(),返回的类型就是传递进来的V类型,并且还可以抛出异常,这也是Runnable接口不具备的
三、Future
先看一下源码
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;
}
Future作用:对实现了Runnable或Callable接口的线程,可以对该线程的执行结果进行取消、查询是否完成、获取结果
下面分别介绍一下它的方法
cancel方法:取消任务,取消任务成功则返回true,取消任务失败则返回false
参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务
如果设置true,则表示可以取消正在执行过程中的任务
1、如果任务已经完成,则无论mayInterruptIfRunning为true还是false,返回false
2、如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,不会去中断已经运行的任务,如果在定时任务中,下一个周期的任务不会运行
3、如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,返回true
isCancelled方法:表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true
isDone方法:表示任务是否已经完成,若任务完成,则返回true
get()方法:用来获取执行结果,阻塞方法,会一直等到任务执行完毕才返回;
get(long timeout, TimeUnit unit)方法:用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
Future只是一个接口,java也为我们提供了一个实现类FutureTask
四、FutureTask
还是先看一下源码
public class FutureTask<V> implements RunnableFuture<V> {//主要了解cancel方法和get方法
}
FutureTask 实现了RunnableFuture接口
public interface RunnableFuture<V> extends Runnable, Future<V> {void run();
}
而RunnableFuture接口又继续了Runnable, Future<V>
所以FutureTask既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
五、demo
public class TestFuture {//定义一个实现了Callable接口的类,主要用来模拟业务,并返回结果//这里假设业务是求1-100的和,把和作为结果返回private static class MyCallable implements Callable<Integer>{private int sum;@Overridepublic Integer call() throws Exception {System.out.println("子线程开始执行");Thread.sleep(2000);for(int i=0;i<100;i++) {sum = sum+i;}System.out.println("子线程执行结束,结果为"+sum);return sum;}}public static void main(String[] args) throws InterruptedException, ExecutionException {//1、创建实现Callable接口的类MyCallable myCallable = new MyCallable();//2、将实现Callable接口的类作为参数,创建FutureTaskFutureTask<Integer> futureTask = new FutureTask<Integer>(myCallable);//3、运行FutureTasknew Thread(futureTask).start();//这里休眠一下,让子线程先执行起来,再取消任务//可以通过这个sleep测试cancel方法,在不同情况下的返回值Thread.sleep(100);//4、如果我们想取消任务,可以调用cancel方法boolean cancel = futureTask.cancel(false);System.out.println(cancel);//5、如果想获取结果,可以调用get方法,注意该方法是阻塞的//futureTask.get();System.out.println("任务结束");}
}
---------------------------------------------------------------------------------------------------------------------------------------------------
如果我的文章对您有点帮助,麻烦点个赞,您的鼓励将是我继续写作的动力
如果哪里有不正确的地方,欢迎指正
如果哪里表述不清,欢迎留言讨论