一, CyclicBarrier (原文链接: http://www.studyshare.cn/blog-front/blog/index http://www.studyshare.cn/blog-front//blog/index )
1, 定义
CyclicBarrier 是线程并发工具类之一, 俗称栅栏. 当一组线程全部执行完后, 到达栅栏屏障, 就放开屏障, 继续往后执行. 举个简单例子: 几个家庭约
定一个地点集合去郊游, 只有当所有家庭都到达后再商量下一步计划, 只要有一个没到, 先到达的家庭都必须等待.
2, 示例 demo
实现: 用 5 个子线程去执行任务, 当任务执行完成后, 交出自己的执行结果, 再被统一释放 (开放栅栏) 去做自己的事情, 而之前 5 个子线程交出的结果
被另外一个线程使用做其他工作.
代码如下:
3, 执行结果:
二, CountDownLatch
1, 定义
CountDownLatch 是线程并发工具类, 该类具有一个计数器, 计数器具有一个初始化的值, 当主线程调用 latch.await()方法则进行阻塞, 调用
latch.countDown()方法时计数器值减一, 一直等到计数器的值减为 0 的时候, 原来阻塞的方法继续往下执行. 代码如下:
(1), 定义两个线程, 线程一调用一次 countDown(), 线程二调用两次 countDown()
(2), 主线程代码如下
(3)运行结果
2, 使用场景
(1), 使用 CountDownLatch 编写高并发测试程序, 可以使用 CountDownLatch 初始化 100 或者更多线程, 当所有线程初始化完毕后
一起去调用需要测试的业务模块代码, 以此来模拟实际场景的高并发访问, 测试业务代码对高并发的支持极限.
(2), 某些系统启动之前需要做很多初始化工作, 只有当初始化工作线程中的所有代码执行完毕后, 才继续执行主线程代码, 此时
使用 CountDownLatch 来实现.
3, 实现原理
CountDownLatch 是基于 AQS(AbstractQueuedSynchronizer (抽象队列同步器))实现的, 关于 AQS 在另外一篇文章有详细讲解, 包
括对源码进行了深入分析, 请参考: http://www.studyshare.cn/blog-front//blog/details/1131/0
三, Semaphore
1, 定义:
Semaphore: 即信号量, 它管理着一组虚拟的许可, 许可的初始数量可通过构造函数指定, 在执行操作时先获取许可(只要还有剩余的
许可), 并在使用后释放许可, 如果没有许可, 则 acquire 方法会阻塞直到有许可. 它提供的 release()方法将返回一个许可给信号量.
2, 关键方法
aquire(): 获取一个虚拟许可, 如果 Semaphore 中还有剩余许可, 则返回, 否则此方法会阻塞, 直到 Semaphore 中有许可为止.
release(): 释放一个虚拟许可回 Semaphore 中
3, 使用场景
使用 Semaphore 实现一个数据库连接池. demo 源码下载(百度网盘: https://pan.baidu.com/s/1B2NEdaXUUnttXN-0ro52NA 提取码: nkyj)
(1)首先定义一个数据库连接实现类, 实现 java.sql.Connection 接口, 如下
说明: java.sql.Connection 实现方法很多, 已省略. 可下载 demo 源码查看
(2)使用 Semaphore 实现数据库连接池, 代码如下:
(3), 运行验证结果分析
来源: https://www.cnblogs.com/darendu/p/10875205.html