ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多线程-ListenableFuture学习(转载)

2022-08-01 17:01:33  阅读:130  来源: 互联网

标签:count 多线程 void ListenableFuture listeningExecutorService new 转载 public


转载:https://www.cnblogs.com/seedss/p/12762209.html

ListenableFuture是可以监听的Future,它是对Java原生的Future进行了拓展和增强。在java中Future表示一个多线程异步执行的任务,当任务执行完成之后可以得到一个计算结果。如果我们希望一旦计算完成之后就可以拿到结果返回或者将结果做另外的计算操作,就必须使用线程去不断查询计算状态。这样做会导致代码复杂,并且计算效率低下。使用ListenableFuture Guava帮我们检测Future是否完成了,如果完成就自动调用回调函数,这样可以减少并发程序的复杂度。

ListenableFuture回调函数有两种方式:

1.通过ListenableFuture的addListener方法

ListenableFuture是一个接口,它从jdk的Future接口继承,添加了void addListener(Runnable listener, Executor executor)方法。

2.通过Futures的静态方法addCallback给ListenableFuture添加回调函数

在调用回调函数之前,首先需要实例化ListenableFuture实例对象。

ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
        ListenableFutureTest test1 = new ListenableFutureTest();
        //获取一个ListenableFuture对象
        ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(test1);

首先通过MoreExecutors类的静态方法listeningDecorator方法初始化一个ListeningExecutorService的方法,然后使用此实例的submit方法即可初始化ListenableFuture对象。

方式1:通过ListenableFuture的addListener方法

代码实例:

复制代码
  private static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));

        ListenableFutureTest test1 = new ListenableFutureTest();

        //获取一个ListenableFuture对象
        ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(test1);

        listenableFuture.addListener(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("线程执行完成后执行该回调函数,线程返回值为:" + listenableFuture.get());
                }catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }, listeningExecutorService);
    }
    
    @Override
    public Integer call() throws Exception {
        while (count.get() < 100) {
            count.getAndIncrement();
            System.out.println(Thread.currentThread().getName() + ":" + count.get());
            Thread.sleep(10);
        }
        return count.get();
    }
复制代码

2.通过Futures的静态方法addCallback给ListenableFuture添加回调函数

复制代码
 1 public static void main(String[] args) throws InterruptedException {
 2         ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
 3         ListenableFutureTest test1 = new ListenableFutureTest();
 4         //获取一个ListenableFuture对象
 5         ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(test1);
 6         //使用addCallback方法
 7         Futures.addCallback(listenableFuture, new FutureCallback<Integer>() {
 8 
 9             @Override
10             public void onSuccess(Integer result) {
11                 System.out.println(Thread.currentThread().getName() + "线程执行结束,返回结果:" + result);
12             }
13 
14             @Override
15             public void onFailure(Throwable t) {
16                 t.printStackTrace();
17             }
18         });
19     }
复制代码

当发生异常时:

复制代码
 1  public static void main(String[] args) throws InterruptedException {
 2         ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
 3         ListenableFutureTest test1 = new ListenableFutureTest();
 4         //获取一个ListenableFuture对象
 5         ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(test1);
 6         Futures.addCallback(listenableFuture, new FutureCallback<Integer>() {
 7 
 8             @Override
 9             public void onSuccess(Integer result) {
10                 System.out.println(Thread.currentThread().getName() + "线程执行结束,返回结果:" + result);
11             }
12 
13             @Override
14             public void onFailure(Throwable t) {
15                 System.out.println(Thread.currentThread().getName() + "线程执行发生异常");
16                 t.printStackTrace();
17             }
18         });
19     }
20 
21     @Override
22     public Integer call() throws Exception {
23         while (count.get() < 100) {
24             count.getAndIncrement();
25             System.out.println(Thread.currentThread().getName() + ":" + count.get());
26             Thread.sleep(10);
27             if (count.get() == 20) {
28                 throw new InterruptedException("异常测试");
29             }
30         }
31         return count.get();
32     }
复制代码

当发生异常时,回调函数输出结果为:

 

 推荐使用第二种方法,因为第二种方法可以直接得到Future的返回值,或者处理错误情况。本质上第二种方法是通过调动第一种方法实现的,做了进一步的封装。

另外ListenableFuture还有其他几种内置实现:

  1. SettableFuture:不需要实现一个方法来计算返回值,而只需要返回一个固定值来做为返回值,可以通过程序设置此Future的返回值或者异常信息
  2. CheckedFuture: 这是一个继承自ListenableFuture接口,他提供了checkedGet()方法,此方法在Future执行发生异常时,可以抛出指定类型的异常。

标签:count,多线程,void,ListenableFuture,listeningExecutorService,new,转载,public
来源: https://www.cnblogs.com/wangbin2188/p/16540908.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有