一、引子

有点经验的工程师一定对多线程比较熟悉,JDK封装的FutureTask实现了这一功能。如下图:

FutureTask实现了RunnableFuture接口,而RunnableFuture接口继承了Future+Runnable共2个接口。因此,FutureTask支持线程执行任务run(),也支持get()等待任务完成、cancel()取消任务等。但是明显还是不够。

Guava的并发包,强大而简单的抽象,让编写正确的并发代码更简单

1.ListenableFuture接口

ListenableFuture接口并继承了JDK concurrent包下的Future 接口。配合Futures工具类,可以很方便的实现以下功能:

1)监听任务执行结果并执行回调方法。

2)提供方便的任务接口转换。

3)多线程并发执行取结果集合。

2.Service框架

抽象可开启和关闭的服务,帮助你维护服务的状态逻辑

二、简单应用

2.1 ListenableFuture接口

2.1.1 监听任务执行结果并执行回调方法

实现功能:

1)定义监听执行器。

2)定义可监听的带返回值任务。

3)定义回调方法。

3)绑定任务、执行器、回调方法。

源码如下:

 public static void main(String[] args) throws ExecutionException, InterruptedException {
/** 1.典型用法:可监听的future,带回调方法 */
// 定义监听执行服务
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
// 定义可监听的带返回值的任务
ListenableFuture<String> callableListenableFuture1 = listeningExecutorService.submit(() -> {
System.out.println("callable1 call!");
return "1";
});
// 添加回调,由指定监听执行服务来执行,监听可监听的future,监听到事件时执行对应回调方法。
Futures.addCallback(callableListenableFuture1, new FutureCallback<String>() {
@Override
public void onSuccess(@Nullable String result) {
System.out.println("success,result=" + result);
} @Override
public void onFailure(Throwable t) {
System.out.println("fail!");
}
}, listeningExecutorService);
}

打印结果:

callable1 call!
success,result=1

2.1.2 提供方便的任务接口转换

实现功能:

1) 定义一个需要绑定的ListenableFuture

2)定义一个异步转换方法

3)定义一个线程任务执行器

4)调用Futures工具类的transformAsync方法实现转换

源码如下:

 public static void main(String[] args) throws ExecutionException, InterruptedException {
/** 2.非典型用法:异步转换 */
// 异步转换,参数1是需要转换的listenableFuture,参数2是转换方法,参数3是执行转换的线程执行器(Runnable)。
ListenableFuture<Integer> transform = Futures.transformAsync(callableListenableFuture1, new AsyncFunction<String, Integer>() {
@Override
public ListenableFuture<Integer> apply(@Nullable String input) {
return Futures.immediateFuture(Integer.parseInt(input));
}
}, MoreExecutors.directExecutor());
// 阻塞线程得到结果
System.out.println("阻塞获取转换后任务的结果:"+transform.get());
}

打印结果:

阻塞获取转换后任务的结果:1

2.1.3 多线程并发执行取结果集合

实现功能:

1)定义多个任务

2)调用Futures工具类的allAsList方法合并结果,返回一个总ListenableFuture,调用get方法即可实现多线程并发执行任务取结果集合,结果是list,顺序是按照提交任务的顺序。

源码如下:

 public static void main(String[] args) throws ExecutionException, InterruptedException {
/** 3.典型用法:多任务并发执行取结果list */
// 可监听不带返回值的任务 ListenableFuture<String> callableListenableFuture2 = listeningExecutorService.submit(() -> {
Thread.sleep(3000);
System.out.println("callable2 call!");
return "2";
});
ListenableFuture<String> callableListenableFuture3 = listeningExecutorService.submit(() -> {
System.out.println("callable3 call!");
return "3";
});
ListenableFuture<List<String>> listListenableFuture = Futures.allAsList(
Lists.newArrayList(callableListenableFuture1, callableListenableFuture2, callableListenableFuture3));
// 返回结果list就是添加任务的顺序
System.out.println("多任务并发执行取结果list result=" + listListenableFuture.get());
}

打印结果:

callable1 call!
callable3 call!
callable2 call!
多任务并发执行取结果list result=[1, 2, 3]

2.2 Service框架

Guava包里的Service接口用于封装一个服务对象的运行状态,包括start和stop等方法。例如web服务器,RPC服务器、计时器等可以实现这个接口。对此类服务的状态管理在多线程环境下尤为复杂。Guava包提供了一些基础类帮助你管理复杂的状态转换逻辑和同步细节。这里不细节拓展,很少情况会用到这个框架。

三、总结

Guava 提供了ListenableFuture接口,结合Futures工具类,可以非常方便的实现并发任务,取结果list等方法,且API优雅易用,在特定场景,建议使用。

相反,Service框架,可能重量级的业务场景才可能使用到,简单场景没有必要使用。

Guava 6:Concurrency的更多相关文章

  1. Google Java编程库Guava介绍

    本系列想介绍下Java下开源的优秀编程库--Guava[ˈgwɑːvə].它包含了Google在Java项目中使用一些核心库,包含集合(Collections),缓存(Caching),并发编程库(C ...

  2. [Java 缓存] Java Cache之 Guava Cache的简单应用.

    前言 今天第一次使用MarkDown的形式发博客. 准备记录一下自己对Guava Cache的认识及项目中的实际使用经验. 一: 什么是Guava Guava工程包含了若干被Google的 Java项 ...

  3. [转载]Google Guava官方教程(中文版)

      原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] ...

  4. Guava学习笔记(一)概览

    Guava是谷歌开源的一套Java开发类库,以简洁的编程风格著称,提供了很多实用的工具类, 在之前的工作中应用过Collections API和Guava提供的Cache,不过对Guava没有一个系统 ...

  5. 使用Guava EventBus构建publish/subscribe系统

    Google的Guava类库提供了EventBus,用于提供一套组件内publish/subscribe的解决方案.事件总线EventBus,用于管理事件的注册和分发.在系统中,Subscribers ...

  6. Guava学习-目录

    备份一下地址: 目录 1. 基本工具 [Basic utilities] 让使用Java语言变得更舒适 1.1 使用和避免null:null是模棱两可的,会引起令人困惑的错误,有些时候它让人很不舒服. ...

  7. Guava学习笔记:Google Guava 类库简介

    http://www.cnblogs.com/peida/tag/Guava/ Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, cachin ...

  8. Guava学习笔记目录

    Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libra ...

  9. Google Guava官方教程(中文版)

    Google Guava官方教程(中文版) 原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ...

随机推荐

  1. fastJson设置接口只接受json格式数据

    spring-mvc/servlet.xml <mvc:annotation-driven> <mvc:message-converters register-defaults=&q ...

  2. FileProvider 添加二级目录

    我们在做Android N升级适配的时候 传统的Intent调用文件的方式会被认为不安全的 然后系统需要让我们使用更加安全的FileProvider的方法去构建intent请求 如 拍照,安装新的ap ...

  3. simple shell

    NOW = $(data + "%Y-%m-%d-%H-%M-%S") DIR = /export/backup function exportData(){ exportCmd ...

  4. 基于Python——实现解压文件夹中的.zip文件

    [背景]当一个文件夹里存好好多.zip文件需要解压时,手动一个个解压再给文件重命名是一件很麻烦的事情,基于此,今天介绍一种使用python实现批量解压文件夹中的压缩文件并给文件重命名的方法—— [代码 ...

  5. .net正则IP加端口,并返回IP加端口

    public string GetIp(string url) { var reg = new Regex(@"\d{2,3}([.]\d{1,3}){3}:\d{2,5}"); ...

  6. 微信小程序textarea组件在fixed定位中随页面滚动

    如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true https://developers.weixin.qq.com/miniprogr ...

  7. 数据的双向绑定 Angular JS之开端篇

    接触AngularJS许了,时常问自己一些问题,如果是我实现它,会在哪些方面选择跟它相同的道路,哪些方面不同.为此,记录了一些思考,给自己回顾,也供他人参考. 初步大致有以下几个方面: 数据双向绑定 ...

  8. javascript的event loop事件循环

    javascript的event loop事件循环 这是今天一个朋友发给我的一个面试题, 感觉还挺有意思的, 写个博客以供分享 先看看这个面试题目: 观察下面的代码,写出输出结果 console.lo ...

  9. 十年京东Java程序员的工作总结,写给迷茫中的你!

    很多年前,刚刚从大学毕业的时候,很多公司来校招.其中最烂俗的一个面试问题是:“你希望你之后三到五年的发展是什么?”.我当时的标准回答是(原话):“成为在某一方面能够独当一面的技术专家“.后来经历了几家 ...

  10. SSM 框架 整合<SpringMVC+Spring+MyBatis>

    一 框架的搭建1.建立一个maven项目 2.建立五个module(entity,dao,service,action,web-view) 3.给予它们之间的依赖关系 dao-->entity ...