Java 的 Future 机制

483 阅读1分钟

Future 机制简介

Java 的 Future 接口是执行异步任务的核心。当我们运行的任务需要较长时间,我们不想要等待它执行完才能去做其他任务时,可以使用异步任务。

比如我们执行任务A,B,C,每个任务执行时间要1s,串行执行时,执行完三个任务大概要3s;使用异步任务,把任务A、B、C都添加到线程池中,交给线程池里的线程执行,在主线程调用 FutureTask.get() 方法获取任务执行的结果,如果任务未执行或在执行中,线程会阻塞,如果任务执行完,会返回执行结果或抛异常,执行完三个任务大概要1s。

代码示例

    @Test
    public void FutureTaskTest(){
        Instant start = Instant.now();
        int res = add(1, 2) + add(3, 4) + add(5, 6);
        Instant end = Instant.now();
        log.info("运行结果:{},运行时间:{}",res,end.toEpochMilli() - start.toEpochMilli());
    }

    //模拟耗时任务
    public int add(int i, int j) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return i + j;
    }

运行结果:21,运行时间:3001

    @Test
    public void FutureTaskTest(){
        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        Instant start = Instant.now();
        //创建任务交给线程池里的线程执行
        Future<Integer> calculateTask1 = executorService.submit(new CalculateTask(1,2));
        Future<Integer> calculateTask2 =executorService.submit(new CalculateTask(3, 4));
        Future<Integer> calculateTask3 =executorService.submit(new CalculateTask(5, 6));
        int res = 0;
        try {
            //异步获取结果
            res = calculateTask1.get(30, TimeUnit.MINUTES) +calculateTask2.get(30, TimeUnit.MINUTES) +calculateTask3.get(30, TimeUnit.MINUTES);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Instant end = Instant.now();
        log.info("运行结果:{},运行时间:{}",res,end.toEpochMilli() - start.toEpochMilli());
    }

    //模拟耗时任务,实现 Callable 接口,call方法里实现任务逻辑
    private class CalculateTask implements Callable<Integer> {

        private int i;
        private int j;

        public CalculateTask(int i,int j){
            this.i = i;
            this.j = j;
        }
        @Override
        public Integer call(){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return i + j;
        }
    }

运行结果:21,运行时间:1003