并发编程系列之Future类的主要功能介绍
2021-12-21 本文已影响0人
smileNicky
并发编程系列之Future类的主要功能介绍
1、什么是Future类?
Future类:future类的是一种异步任务监视器,可以让提交者可以监视任务的执行,同时可以取消任务的执行,也可以获取任务返回结果
2、Future类的作用
比如在做一定的任务运算的时候,需要等待比较长时间,这个任务是比较耗时的,需要比较繁重的运算,比如加密、压缩等等。如果一直在等程序执行完成是不明智的,这时可以将这个比较耗时的任务交给子线程执行,然后通过Future类监控线程执行,获取返回的结果。这样一来就提高了工作效率,这是一种异步的思想。
3、Future方法和用法
通过idea看一下Future类的类学习,可以看到这个类只有5个方法,基于jdk1.8:
在这里插入图片描述
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, TimeoutExceptio
}
-
cancel(boolean mayInterruptIfRunning)
:取消任务的执行
执行这个方法时候,会有三种情况,- 第一种情况,任务还没开始执行,调用了这个方法,这种情况比较好理解,这个任务会被正常取消,然后返回true
- 第二种情况,也比较简单,假如任务已经执行完成或者是已经执行过一次取消任务的方法,这种情况如果再调用这个方法,是会取消失败的,返回false。因为任务无论是已完成还是已经被取消过了,都不能再被取消了
- 第三种情况,是任务正在执行,这种情况就会根据我们传入的
mayInterruptIfRunning
参数进行分情况调用,如果这个值为true,执行任务的线程就会收到一个中断的信号,然后执行中断任务的逻辑,然后返回。如果这种值为false,任务就不会被取消,继续执行,同时会返回false,表示不执行取消任务操作
-
isCancelled()
:获取是否取消了任务
这个方法用于判断任务是否被取消了,比较简单 -
isDone()
:任务是否执行完成
这个方法如果返回true,则表示执行完成了,返回false,表示还没执行完成。这里有一种特殊情况需要特别注意,就是如果执行任务的过程发生了Exception,这种情况还是会被当成执行完成的,因为抛出Exception的任务,在”Future“也是不会执行的,所以都当成执行完成返回true -
get()
和get(long timeout, TimeUnit unit)
:获取任务执行的返回值
get
方法最主要的作用就是获取任务返回的结果,get
方法可能会发生以下 5 种情况:- 第一种情况:任务执行完成了,这种情况好办,直接返回任务执行结果
- 第二种情况:任务还没执行完成,这种情况有可能是任务本身业务比较复杂,需要花比较长时间,也有可能是放在线程池里,然后线程池堆积了不少任务,所以需要线程等待,这种情况调用get方法,都会把当前的线程阻塞,直到任务完成再把结果返回回来。
- 第三种情况:执行任务过程抛出了异常,这种情况调用get会返回
ExecutionException
,不管实际的异常类型是什么
public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService service = new ThreadPoolExecutor(10, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(10)); Future<Integer> future = service.submit(new CallableTask()); System.out.println(future.get()); service.shutdown(); } static class CallableTask implements Callable<Integer> { @Override public Integer call() throws Exception{ throw new IllegalArgumentException("callable exception"); } }
执行抛出异常:`Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: callable exception `
* 第四种情况:**任务被取消了**,这种情况调用get方法会抛出`CancellationException`
* 第五种情况:**任务超时执行**,这种情况是针对`get(long timeout, TimeUnit unit)`这个方法来说的,我们设置了`timeout`超时时长,如果超过了设定的值,就会抛出`TimeoutException`
在这里插入图片描述
package com.example.concurrent.future;
import java.util.Random;
import java.util.concurrent.*;
/**
* <pre>
* Future例子
* </pre>
* <p>
* <pre>
* @author nicky.ma
* 修改记录
* 修改后版本: 修改人: 修改日期: 2021/08/28 17:11 修改内容:
* </pre>
*/
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = new ThreadPoolExecutor(10, 10,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(10));
Future<Integer> future = service.submit(new CallableTask());
System.out.println(future.get());
service.shutdown();
}
static class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception{
Thread.sleep(1000L);
return new Random().nextInt();
}
}
}