阿里规范(一)关于CountDownLatch和ThreadLocalRandom的详解(带测试代码)

本文主要是介绍阿里规范(一)关于CountDownLatch和ThreadLocalRandom的详解(带测试代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近看了阿里代码规范,较之前相比加入了许多java的新特性。最新的文档有一定的门槛,比如有些是阿里dubbo特有的规范,可能我们用不到,只需结合自身实际合理借鉴即可。给我印象最深的是集合和线程的规范,这两部分我写了不少的测试例子,写几篇博客给大家分享一下,喜欢的可以点击关注。(笔者推荐学习文档时配合阿里代码扫描插件,有eclipse版idea版)。

阿里规范原文(1):使用 CountDownLatch 进行异步转同步操作,每个线程退出前必须调用 countDown 方法,线程执行代码注意 catch 异常,确保 countDown 方法被执行到,避免主线程无法执行至 await 方法,直到超时才返回结果。

阿里规范原文(2):避免 Random 实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed 导致的性能下降。在 JDK7 之后,可以直接使用 API ThreadLocalRandom,而在 JDK7 之前,需要编码保证每个线程持有一个实例。

这两个规范我放在一个例子里测试,大家可以直接复制运行。

业务场景

火箭发射前需要做各种检查,等各种检查完毕之后,点火,火箭发射。在这里发射前的各种检查是并行的(文档中的异步),检查和火箭发射是有顺序要求的(同步)。

测试代码
public class CountDownLatchDemo implements Runnable{static final CountDownLatch latch = new CountDownLatch(10);static final CountDownLatchDemo demo = new CountDownLatchDemo();@Overridepublic void run() {// 模拟检查任务try {/**测试多线程情况下 Random 和  ThreadLocalRandom 的性能, 对应文档的1.6.14 */Thread.sleep(ThreadLocalRandom.current().nextInt(10) * 1000);//Thread.sleep(new Random().nextInt(10) * 1000);//System.out.println("check complete");//计数减一latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException {long currentTimeMillis = System.currentTimeMillis();ExecutorService exec = Executors.newFixedThreadPool(10);for (int i=0; i<100; i++){exec.submit(demo);}// 等待火箭发射前的各种检查(主线程等待所有子线程执行完成,再向下执行)latch.await();// 发射火箭System.out.println("Fire!");// 关闭线程池exec.shutdown();System.out.println("耗时:" + (System.currentTimeMillis() - currentTimeMillis));}
}
说明一(CountDownLatch )

1、例子中我假设做了10次检查,对应10个异步的子线程。
2、在子线程执行时,主线程等待(latch.await())。
3、子线程每次执行完退出前计数器减1。
4、等所有子线程全部执行完毕(计数器为0),此时执行主线程(发射火箭)。

说明二(ThreadLocalRandom)

1、测试结果很明显ThreadLocalRandom要快很多,数据越大时越准确(我的结果是9010和5007,能优化至少1/3)。
2、原理:多线程在访问Random()时会有竞争,导致性能下降(线程饥饿)。而ThreadLocalRandom是jdk1.7后提供的并发产生随机数,能够解决多个线程发生的竞争。
3、想要更深了解的可以查看jdk源码。

这篇关于阿里规范(一)关于CountDownLatch和ThreadLocalRandom的详解(带测试代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/810475

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input