您的位置:首页 > 其它

线程中的Callable、Future 和FutureTask

2020-07-14 06:31 239 查看

1.三者的关系

2.FutureTask的概述

三种执行状态:
1、未启动:在FutureTask.run()还没执行之前,FutureTask处于未启动状态。当创建一个FutureTask对象,并且run()方法未执行之前,FutureTask处于未启动状态。
2、已启动:FutureTask对象的run方法启动并执行的过程中,FutureTask处于已启动状态。
3、已完成:FutureTask正常执行结束,或者FutureTask执行被取消(FutureTask对象cancel方法),或者FutureTask对象run方法执行抛出异常而导致中断而结束,FutureTask都处于已完成状态。

state:表示当前任务的运行状态,FutureTask的所有方法都是围绕state开展的,state声明为volatile,保证了state的可见性,当对state进行修改时所有的线程都会看到。
NEW:表示一个新的任务,初始状态
COMPLETING:当任务被设置结果时,处于COMPLETING状态,这是一个中间状态。
NORMAL:表示任务正常结束。
EXCEPTIONAL:表示任务因异常而结束
CANCELLED:任务还未执行之前就调用了cancel(true)方法,任务处于CANCELLED
INTERRUPTING:当任务调用cancel(true)中断程序时,任务处于INTERRUPTING状态,这是一个中间状态。
INTERRUPTED:任务调用cancel(true)中断程序时会调用interrupt()方法中断线程运行,任务状态由INTERRUPTING转变为INTERRUPTED

可能的状态过渡:
1、NEW -> COMPLETING -> NORMAL:正常结束
2、NEW -> COMPLETING -> EXCEPTIONAL:异常结束
3、NEW -> CANCELLED:任务被取消
4、NEW -> INTERRUPTING -> INTERRUPTED:任务出现中断

3.FutureTask类的使用场景

当一个线程需要等待另一个线程把某个任务执行完后它才能继续执行,此时可以使用FutureTask。可以获取线程执行的返回结果。

4.相关api

FutureTask实现了Future接口,Future接口有5个方法:

/*尝试取消当前任务的执行。如果任务已经取消、已经完成或者其他原因不能取消,尝试将失败。
如果任务还没有启动就调用了cancel(true),任务将永远不会被执行。
如果任务已经启动,参数mayInterruptIfRunning将决定任务是否应该中断执行该任务的线程,
以尝试中断该任务。如果任务不能被取消,通常是因为它已经正常完成,此时返回false,否则返回true*/
1、boolean cancel(boolean mayInterruptIfRunning)

//如果任务在正常结束之前被被取消返回true
2、boolean isCancelled()

//正常结束、异常或者被取消导致任务完成,将返回true
3、boolean isDone()

/*等待任务结束,然后获取结果,如果任务在等待过程中被终端将抛出InterruptedException,
如果任务被取消将抛出CancellationException,如果任务中执行过程中发生异常
将抛出ExecutionException。*/
4、V get()

//任务最多在给定时间内完成并返回结果,如果没有在给定时间内完成任务将抛出TimeoutException。
5、V get(long timeout, TimeUnit unit)

5.简单例子

/*实现Callable接口,允许有返回值*/
private static class UseCallable implements Callable<Integer>{
private int sum;
@Override
public Integer call() throws Exception {
System.out.println("Callable子线程开始计算!");
//			Thread.sleep(1000);
for(int i=0 ;i<5000;i++){
if(Thread.currentThread().isInterrupted()) {
System.out.println("Callable子线程计算任务中断!");
return null;
}
sum=sum+i;
System.out.println("sum="+sum);
}
System.out.println("Callable子线程计算结束!结果为: "+sum);
return sum;
}
}

public static void main(String[] args)
throws InterruptedException, ExecutionException {

UseCallable useCallable = new UseCallable();
//包装
FutureTask<Integer> futureTask = new FutureTask<>(useCallable);
Random r = new Random();
new Thread(futureTask).start();

Thread.sleep(1);
if(r.nextInt(100)>50){
System.out.println("Get UseCallable result = "+futureTask.get());
}else{
System.out.println("Cancel................. ");
futureTask.cancel(true);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: