一、Future的应用场景

Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来进行异步计算。有了Future就可以进行三段式的编程了,1.启动多线程任务2.处理其他事3.收集多线程任务结果。从而实现了非阻塞的任务调用。在途中遇到一个问题,那就是虽然能异步获取结果,但是Future的结果需要通过isdone来判断是否有结果,或者使用get()函数来阻塞式获取执行结果。这样就不能实时跟踪其他线程的结果状态了,所以直接使用get还是要慎用,最好配合isdone来使用。

在并发编程中,我们经常用到非阻塞的模型,在之前的多线程的三种实现中,不管是继承thread类还是实现runnable接口,都无法保证获取到之前的执行结果。通过实现Callable接口,并用Future可以来接收多线程的执行结果。Future表示一个可能还没有完成的异步任务的结果,针对这个结果可以添加Callable以便在任务执行成功或失败后作出相应的操作。

二、Future类图结构

Future接口定义了主要的5个接口方法,有RunnableFuture和SchedualFuture继承这个接口,以及CompleteFuture和ForkJoinTask继承这个接口。

java future 可以get两次么 java future isdone_多线程

三、Future的主要方法

Future接口主要包括5个方法:

1、get() 方法可以当任务结束后返回一个结果,如果调用时,工作还没有结束,则会阻塞线程,直到任务执行完。
2、get(long timeout,TimeUnit unit) 做多等待timeout的时间就会返回结果.。
3、cancel(boolean mayInterruptIfRunning) 方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
4、isDone() 方法判断当前方法是否完成。
5、isCancel() 方法判断当前方法是否取消。

四、Future实例Demo

package future;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class FutureTest {

    private static ExecutorService executor = Executors.newCachedThreadPool();

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Future<Integer> future1 = calculate(1);
        Future<Integer> future2 = calculate(2);
        Future<Integer> future3 = calculate(3);
        while(!future1.isDone() && !future2.isDone() && !future3.isDone()) {
            System.out.println(future1.isDone()+" "+future2.isDone()+" "+future3.isDone());
        }
        System.out.println(future1.get()+" "+future2.get()+" "+future3.get());

    }

    public static Future<Integer> calculate(Integer input) {
        return executor.submit(() -> {
            Thread.sleep(1000);
            return input * input;
        });
    }

}