Future清清白白的接口
Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
出现它是源于,1.5之前的线程运行完之后是没有返回值的 runnable -void ,有些场景不是很方便,出现callable,有了返回值,返回一个Future<T>
O~~NO,这个不是很难,我就引用网上的小伙伴的总结了
在Future接口中声明了5个方法,下面依次解释每个方法的作用:
- cancel 方法用来取消任务,取消任务成功返回true,取消任务失败返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,true表示可以取消正在执行过程中的任务。
- 1.如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true;
- 2.如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,设置为false,则返回false;
- 3. 如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false。
-
public boolean cancel(boolean mayInterruptIfRunning) { // 猜测:当前线程要是 NEW 【noFinish的线程-包含未执行过和正在执行的状态】,且执行了 // UNSAFE方法【将线程的NEW状态变成-mayInterruptIfRunning ? INTERRUPTING : // CANCELLED】 成功,就继续执行 if (!(state == NEW && UNSAFE.compareAndSwapInt(this, stateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); } } } finally { finishCompletion(); } return true; }
- isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
- isDone方法表示任务是否已经完成,若任务完成,则返回true;
- get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
- get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
ps.补充
2019/02/16:昨天在一个地方看到cancel() 的解释有出入 ,特地写了方法测试debug一波,我是对的:
public static void main(String[] args) { int threadSum = 10; try { ThreadPoolExecutor tpe = new ThreadPoolExecutor(1,1, 0, TimeUnit.MICROSECONDS,new LinkedBlockingQueue<>(5),new ThreadPoolExecutor.DiscardOldestPolicy()); ArrayList<Future<String>> fts = new ArrayList<>(threadSum); for (int i = 0;i<threadSum;i++){ final int no=i; Callable<String> cal = ()->{ String threadName = Thread.currentThread().getName(); System.out.println(threadName + "--" + no +" -- begin sleep 3s" ); Thread.sleep(6000); System.out.println(threadName + "--" + no +" -- finish sleep" ); return threadName; }; fts.add(tpe.submit(cal)); } Thread.sleep(2000); fts.forEach(f -> { String threadName = Thread.currentThread().getName(); System.out.println(); System.out.println(threadName + "-- f.isDone() --" + f.isDone()); System.out.println(threadName + "-- f.isCancelled() --" + f.isCancelled()); System.out.println(threadName + "-- f.cancel(true) --" + f.cancel(false)); }); Thread.sleep(7000); tpe.shutdown(); } catch (Exception e) { e.printStackTrace(); } finally { } }