java中Future使用方法举例详细介绍

 更新时间:2025年01月09日 10:50:05   作者:时间_wys  
Future是java5新加的一个接口,提供了异步并行计算的功能,这篇文章主要介绍了java中Future使用方法绍的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、什么是Future?

在并发编程中,可以通过Future对象来异步获取结果

使用Thread或runnable接口都不能获取异步的执行结果,因为他们没有返回值。而通过实现Callable接口和Future就可以获取异步执行的结果,当异步执行结束后,返回结果将保存在Future中。使用Future就可以让我们暂时去处理其他的任务而无需一直等待结果,等异步任务执行完毕再返回其结果。

二、Future中的get方法

1、get方法

获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,直到任务完成。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。

V get() throws InterruptedException, ExecutionException;

2、指定时间的get方法

获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,等待一定时间,如果在规定时间内任务结束则返回结果,否则抛出TimeoutException,超时后任务依旧会继续执行。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

三、Future代码示例

步骤1:创建一个线程池

public class AsyncTaskExecutor {
    /**
     * 核心线程数
     */
    private static final int corePoolSize = 10;

    /**
     * 最大线程数
     */
    private static final int maxPoolSize = 30;

    /**
     * 空闲线程回收时间
     * 空闲线程是指:当前线程池中超过了核心线程数之后,多余的空闲线程的数量
     */
    private static final int keepAliveTime = 100;

    /**
     * 任务队列/阻塞队列
     */
    private static final int blockingQueueSize = 99999;

    private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            keepAliveTime,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(blockingQueueSize),
            new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    /**
     * 异步任务执行
     *
     * @param task
     */
    public static void execute(Runnable task) {
        executorPool.execute(task);
    }

    /**
     * 异步执行任务Callable, 通过Future获取结果
     *
     * @param task
     * @param <T>
     * @return
     */
    public static <T> Future<T> submit(Callable<T> task) {
        return executorPool.submit(task);
    }

    /**
     * 异步执行任务Runnable,通过Future获取结果
     *
     * @param task
     * @return
     */
    public static Future<?> submit(Runnable task) {
        return executorPool.submit(task);
    }
}

步骤2:编写测试类

    @Test
    public void test2() {
        try {
            Future<String> future = AsyncTaskExecutor.submit(() -> {
                log.info("[Future Task] future task start...");
                try {
                    //模拟任务执行
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    log.info(e.getMessage());
                }
                log.info("[Future Task] future task end...");
                return "Task completed...";
            });

            //执行其他任务
            log.info("[Main Thread] main thread is running...");

            //使用future阻塞等待任务完成,并获取结果
            String futureResult = future.get();
            log.info("[Main Thread] {}", futureResult);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

步骤3:查看结果

2024-05-28 10:58:23.633  INFO 1184 --- [           main] com.example.demo.dao.UserDaoTest         : [Main Thread] main thread is running...
2024-05-28 10:58:23.633  INFO 1184 --- [yncTaskThread-0] com.example.demo.dao.UserDaoTest         : [Future Task] future task start...
2024-05-28 10:58:28.633  INFO 1184 --- [yncTaskThread-0] com.example.demo.dao.UserDaoTest         : [Future Task] future task end...
2024-05-28 10:58:28.634  INFO 1184 --- [           main] com.example.demo.dao.UserDaoTest         : [Main Thread] Task completed...

四、ListenableFuture

public class AsyncTaskExecutor {
    /**
     * 核心线程数
     */
    private static final int corePoolSize = 10;

    /**
     * 最大线程数
     */
    private static final int maxPoolSize = 30;

    /**
     * 空闲线程回收时间
     * 空闲线程是指:当前线程池中超过了核心线程数之后,多余的空闲线程的数量
     */
    private static final int keepAliveTime = 100;

    /**
     * 任务队列/阻塞队列
     */
    private static final int blockingQueueSize = 99999;

    private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            keepAliveTime,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(blockingQueueSize),
            new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    /**
     * 创建一个ListeningExecutorService,用于执行异步任务
     * (通过submit提交任务,以ListenableFuture获取结果)
     */
    private static final ListeningExecutorService LISTENING_EXECUTOR = MoreExecutors.listeningDecorator(executorPool);

    /**
     * 异步任务执行
     *
     * @param task
     */
    public static void execute(Runnable task) {
        executorPool.execute(task);
    }

    /**
     * 异步执行任务Callable, 通过ListenableFuture获取结果
     *
     * @param task
     * @param <T>
     * @return
     */
    public static <T> ListenableFuture<T> submit(Callable<T> task) {
        return LISTENING_EXECUTOR.submit(task);
    }

    /**
     * 异步执行任务Runnable,通过Future获取结果
     *
     * @param task
     * @return
     */
    public static ListenableFuture<?> submit(Runnable task) {
        return LISTENING_EXECUTOR.submit(task);
    }
}
	//示例1:
    @Test
    public void test2() {
       ListenableFuture<School> listenableFuture1 = AsyncTaskExecutor.submit(() -> {
                try {
                    //模拟任务执行
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    log.info(e.getMessage());
                }
                return new School("DSchool");
            });
            ListenableFuture<School> listenableFuture2 = AsyncTaskExecutor.submit(() -> {
                try {
                    //模拟任务执行
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    log.info(e.getMessage());
                }
                return new School("ESchool");
            });

            //阻塞等待,直到listenableFuture1 和 listenableFuture2都获取到结果后或其中一个异常
            Futures.successfulAsList(listenableFuture1, listenableFuture2).get();
            School resSchool1 = listenableFuture1.get();
            School resSchool2 = listenableFuture2.get();
            log.info("[Main Thread] result1 is {}", JSON.toJSONString(resSchool1));
            log.info("[Main Thread] result2 is {}", JSON.toJSONString(resSchool2));

            //任意位置即时设定ListenableFuture的返回结果
            ListenableFuture<School> listenableFuture3 = Futures.immediateFuture(new School("aaa"));
            ListenableFuture<School> listenableFuture4 = Futures.immediateFailedFuture(new Exception("eeee"));
            log.info("[Main Thread] listenableFuture3 is {}", listenableFuture3.get());
            log.info("[Main Thread] listenableFuture4 is {}", listenableFuture4.get());
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    
	//示例2:
    public static void main(String[] args) {
        // 创建一个ListeningExecutorService,用于执行异步任务
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());

        // 提交一个异步任务,并得到ListenableFuture对象
        ListenableFuture<String> listenableFuture = executor.submit(() -> {
            // 模拟耗时操作
            Thread.sleep(2000);
            return "Result of the asynchronous computation";
        });

        // 注册异步操作完成时的回调函数
        Futures.addCallback(listenableFuture, new FutureCallback<String>() {
            @Override
            public void onSuccess(String result) {
                System.out.println("Result: " + result);
                executor.shutdown(); // 关闭executor
            }

            @Override
            public void onFailure(Throwable t) {
                t.printStackTrace();
                executor.shutdown(); // 关闭executor
            }
        }, executor);
    }

五、CompletableFuture

	//示例1:
	public static void main(String[] args) {
        // 创建一个CompletableFuture对象
        CompletableFuture<School> completableFuture = new CompletableFuture<>();

        // 异步任务:模拟一个耗时操作
        new Thread(() -> {
            try {
                // 模拟耗时操作
                Thread.sleep(2000);
                // 完成CompletableFuture并设置值
                completableFuture.complete(new School("completableSchool"));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 在这里等待异步任务的结果并输出
        try {
            School result = completableFuture.get();
            log.info("[CompletableFuture] result is {}" ,result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

	//示例2:
    @Test
    public void test2() {
        try {
            //创建一个CompletableFuture对象
            CompletableFuture<School> schoolFuture = new CompletableFuture<>();
            //任意位置即时设定CompletableFuture的返回结果
            schoolFuture.complete(new School("FSchool"));
            School school = schoolFuture.get();
            log.info("[Main Thread] result is {}", JSON.toJSONString(school));
            
        }catch (Exception e) {
            log.info(e.getMessage());
        }
    }

六、SettableFuture

	//示例1:
	public static void main(String[] args) {
        // 创建一个SettableFuture对象
        SettableFuture<String> settableFuture = SettableFuture.create();

        // 手动设置异步操作的结果
        settableFuture.set("Result of the asynchronous computation");

        // 注册异步操作完成时的回调函数
        settableFuture.addListener(() -> {
            try {
                String result = settableFuture.get(); // 获取异步操作的结果
                System.out.println("Result: " + result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, Runnable::run);
    }
    
	//示例2:
	@Test
    public void test2() {
        try {
            //创建一个SettableFuture对象
            SettableFuture<School> settableFuture = SettableFuture.create();
            //任意位置即时设定SettableFuture的返回结果
            settableFuture.set(new School("GSchool"));
            School setSchool = settableFuture.get();
            log.info("[Main Thread] setSchool is {}", JSON.toJSONString(setSchool));
            
        }catch (Exception e) {
            log.info(e.getMessage());
        }
    }

总结 

到此这篇关于java中Future使用方法的文章就介绍到这了,更多相关java中Future使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中集合LinkedList的原理与使用方法

    Java中集合LinkedList的原理与使用方法

    这篇文章主要给大家介绍了关于Java中集合LinkedList的原理与使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • 基于Java事件监听编写一个中秋猜灯谜小游戏

    基于Java事件监听编写一个中秋猜灯谜小游戏

    众所周知,JavaSwing是Java中关于窗口开发的一个工具包,可以开发一些窗口程序,然后由于工具包的一些限制,导致Java在窗口开发商并没有太多优势,不过,在JavaSwing中关于事件的监听机制是我们需要重点掌握的内容,本文将基于Java事件监听编写一个中秋猜灯谜小游戏
    2023-09-09
  • Springboot手动连接库并获取指定表结构的示例代码

    Springboot手动连接库并获取指定表结构的示例代码

    这篇文章主要介绍了Springboot手动连接库并获取指定表结构的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java日常练习题,每天进步一点点(42)

    Java日常练习题,每天进步一点点(42)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • Java中system.exit(0) 和 system.exit(1)区别

    Java中system.exit(0) 和 system.exit(1)区别

    本文主要介绍了Java中system.exit(0) 和 system.exit(1)区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • SpringBoot中@ConfigurationProperties注解实现配置绑定的三种方法

    SpringBoot中@ConfigurationProperties注解实现配置绑定的三种方法

    这篇文章主要介绍了SpringBoot中@ConfigurationProperties注解实现配置绑定的三种方法,文章内容介绍详细需要的小伙伴可以参考一下
    2022-04-04
  • Java中Map的排序问题详解

    Java中Map的排序问题详解

    本文给大家分享的是java中的map的按值排序和按键排序问题,并通过具体的示例,希望对大家能有所帮助。
    2016-01-01
  • Java之SSM中bean相关知识汇总案例讲解

    Java之SSM中bean相关知识汇总案例讲解

    这篇文章主要介绍了Java之SSM中bean相关知识汇总案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Java DOM4J方式生成XML的方法

    Java DOM4J方式生成XML的方法

    今天小编就为大家分享一篇Java DOM4J方式生成XML的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • IDEA 2020.1 搜索不到Chinese ​(Simplified)​ Language Pack EAP,无法安装的问题

    IDEA 2020.1 搜索不到Chinese ​(Simplified)​ Language

    小编在安装中文插件时遇到IDEA 2020.1 搜索不到Chinese &#8203;(Simplified)&#8203; Language Pack EAP,无法安装的问题,本文给大家分享我的解决方法,感兴趣的朋友一起看看吧
    2020-04-04

最新评论