24.线程系列- google提供的一些好用的并发工具类
关于并发方面,juc已帮我们提供了很多好用的工具,而谷歌在此基础上做了扩展,使并发更容易,这些工具放在guava.jar包中。
本文演示几个简单的案例,见一下guava的效果。
guava maven配置
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>27.0-jre</version>
</dependency>
guava中常用几个类
MoreExecutors:提供了一些静态方法,是对juc中的Executors类的一个扩展
Future:也提供了很多静态方法,是对juc中Future的一个扩展
案例1:异步执行任务完毕之后回调
public class Demo1 {public static void main(String[] args) throws ExecutionException, InterruptedException {//创建一个线程池ExecutorService executorService = Executors.newFixedThreadPool(5);ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);try {ListenableFuture<Integer> listenableFuture = listeningExecutorService.submit(() -> {System.out.println(System.currentTimeMillis());//休眠2秒,默认耗时TimeUnit.SECONDS.sleep(2);System.out.println(System.currentTimeMillis());return 10;});listenableFuture.addListener(()->{System.out.println("回调");},MoreExecutors.directExecutor());System.out.println(listenableFuture.get());}finally {listeningExecutorService.shutdown();}}
}
输出:
1608615858082
1608615860082
回调
10
另外一种写法:
public class Demo2 {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService delegate = Executors.newFixedThreadPool(5);try {ListeningExecutorService executorService = MoreExecutors.listeningDecorator(delegate);ListenableFuture<Integer> submit = executorService.submit(() -> {System.out.println(System.currentTimeMillis());TimeUnit.SECONDS.sleep(4);int i = 10 / 0;System.out.println(System.currentTimeMillis());return 10;});Futures.addCallback(submit, new FutureCallback<Integer>() {@Overridepublic void onSuccess(@Nullable Integer result) {System.out.println("执行成功" + result);}@Overridepublic void onFailure(Throwable t) {try {TimeUnit.MILLISECONDS.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("执行任务发生异常:" + t.getMessage());}}, MoreExecutors.directExecutor());System.out.println(submit.get());} finally {delegate.shutdown();}}
}
输出:
1608615899714
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zeroat com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:552)at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:533)at com.google.common.util.concurrent.FluentFuture$TrustedFuture.get(FluentFuture.java:82)at com.example.thread.guava.Demo2.main(Demo2.java:40)
Caused by: java.lang.ArithmeticException: / by zeroat com.example.thread.guava.Demo2.lambda$main$0(Demo2.java:20)at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:125)at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:57)at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:78)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)at java.lang.Thread.run(Thread.java:745)
执行任务发生异常:/ by zero
上面通过调用Futures
的静态方法addCallback
在异步执行的任务中添加回调,回调的对象是一个FutureCallback
,此对象有2个方法,任务执行成功调用onSuccess
,执行失败调用onFailure
。
示例2:获取一批异步任务的执行结果
@Slf4j
public class Demo3 {public static void main(String[] args) throws ExecutionException, InterruptedException {log.info("star");ExecutorService delegate = Executors.newFixedThreadPool(5);try {ListeningExecutorService executorService = MoreExecutors.listeningDecorator(delegate);List<ListenableFuture<Integer>> futureList = new ArrayList<>();for (int i = 5; i >= 0; i--) {int j = i;futureList.add(executorService.submit(() -> {TimeUnit.SECONDS.sleep(j);return j;}));}//获取一批任务的执行结果List<Integer> resultList = Futures.allAsList(futureList).get();//输出resultList.forEach(item -> {log.info("{}", item);});} finally {delegate.shutdown();}}
}
14:26:35.970 [main] INFO com.itsoku.chat34.Demo3 - star
14:26:41.137 [main] INFO com.itsoku.chat34.Demo3 - 5
14:26:41.138 [main] INFO com.itsoku.chat34.Demo3 - 4
14:26:41.138 [main] INFO com.itsoku.chat34.Demo3 - 3
14:26:41.138 [main] INFO com.itsoku.chat34.Demo3 - 2
14:26:41.138 [main] INFO com.itsoku.chat34.Demo3 - 1
14:26:41.138 [main] INFO com.itsoku.chat34.Demo3 - 0
结果中按顺序输出了6个异步任务的结果,此处用到了Futures.allAsList
方法,看一下此方法的声明:
public static <V> ListenableFuture<List<V>> allAsList(Iterable<? extends ListenableFuture<? extends V>> futures)
传递一批ListenableFuture
,返回一个ListenableFuture<List<V>>
,内部将一批结果转换为了一个ListenableFuture
对象。
示例3:一批任务异步执行完毕之后回调
@Slf4j
public class Demo4 {public static void main(String[] args) throws ExecutionException, InterruptedException {log.info("star");ExecutorService delegate = Executors.newFixedThreadPool(5);try {ListeningExecutorService executorService = MoreExecutors.listeningDecorator(delegate);List<ListenableFuture<Integer>> futureList = new ArrayList<>();for (int i = 5; i >= 0; i--) {int j = i;futureList.add(executorService.submit(() -> {TimeUnit.SECONDS.sleep(j);return j;}));}ListenableFuture<List<Integer>> listListenableFuture = Futures.allAsList(futureList);Futures.addCallback(listListenableFuture, new FutureCallback<List<Integer>>() {@Overridepublic void onSuccess(@Nullable List<Integer> result) {log.info("result中所有结果之和:" + result.stream().reduce(Integer::sum).get());}@Overridepublic void onFailure(Throwable t) {log.error("执行任务发生异常:" + t.getMessage(), t);}}, MoreExecutors.directExecutor());} finally {delegate.shutdown();}}
}
输出:
14:47:04.819 [main] INFO com.itsoku.chat34.Demo4 - star
14:47:09.933 [pool-1-thread-1] INFO com.itsoku.chat34.Demo4 - result中所有结果之和:15
代码中异步执行了一批任务,所有任务完成之后,回调了上面的onSuccess
方法,内部对所有的结果进行sum操作。
总结
通过guava提供的一些工具类,方便异步执行任务并进行回调
guava内部还有很多好用的工具类,有兴趣的可以去研究一下
24.线程系列- google提供的一些好用的并发工具类相关推荐
- 【kafka】google提供的一些好用的并发工具类
1.概述 环境:jdk1.8. 关于并发方面的,juc已帮我们提供了很多好用的工具,而谷歌在此基础上做了扩展,使并发编程更容易,这些工具放在guava.jar包中. 本文演示几个简单的案例,见一下gu ...
- 并发工具类(四)两个线程进行数据交换的Exchanger
简介 Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法 ...
- Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解
之前谈过高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 ,以及高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8) 今天主要介绍concurre ...
- 【搞定Java并发编程】第24篇:Java中的并发工具类之CountDownLatch
上一篇:Java中的阻塞队列 BlockingQueue 详解 本文目录: 1.CountDownLatch的基本概述 2.CountDownLatch的使用案例 3.CountDownLatch的源 ...
- j.u.c系列(11)---之并发工具类:Exchanger
写在前面 前面三篇博客分别介绍了CyclicBarrier.CountDownLatch.Semaphore,现在介绍并发工具类中的最后一个Exchange.Exchange是最简单的也是最复杂的,简 ...
- 并发工具类(四)线程间的交换数据 Exchanger
前言 JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Ph ...
- j.u.c系列(08)---之并发工具类:CountDownLatch
写在前面 CountDownLatch所描述的是"在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待":用给定的计数 初始化 CountDownLatch.由于调 ...
- 线程池、volatile、原子性、并发工具类
目录 线程状态 线程池-基本原理 线程池 - Executors默认线程池 线程池 - ThreadPoolExecutor 线程池参数-拒绝策略 volatile 原子性 原子性 - AtomicI ...
- 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)
文章目录 八.Java中的并发工具类 8.1 等待多线程完成的CountDownLatch 8.2 同步屏障CyclicBarrier 8.2.1 CyclicBarrier简介 8.2.2 Cycl ...
最新文章
- vue修改节点class_Vue2.0 源码解读系列 来自 Vue 的神秘礼盒
- Java对象间的转化
- Linux下ntpdate时间同步
- PHP中4个包含文件方法的差异
- Python collections的使用
- python 描述统计_Python统计学-004:描述统计-众数
- 在Linux和qt下安装EasyPr遇到的问题
- python漏洞扫描器编写_漏洞扫描器开发与设计的一点感悟
- JavaScript封装回调函数(委托)
- 共享租赁汽车,必将重新设计中国汽车产业链游戏规则
- Redis数据库常用命令(超级详细)
- NRF52840 SOC 在空气净化市场应用的发展趋势
- Python+班级管理系统 毕业设计-附源码171809
- Redhat7升级内核(含安装yum)
- OSChina 周二乱弹 ——追妹子最管用的方式
- java sleep唤醒_详解Java中的线程让步yield()与线程休眠sleep()方法
- 多功能在线起名取名查重工具微信小程序源码 可开流量主 带安装教程
- 拨号上网怎么修改dns服务器,dns怎么设置才能上网 dns设置上网方法【图文】
- 全文索引JAVA_全文索引Sphinx和sphinx的中文分词
- c语言判断闰年星期几,C语言判断闰年