Java的几个同步辅助类

Java为我们提供了一些同步辅助类,利用这些辅助类我们可以在多线程编程中,灵活地把握线程的状态。

CountDownLatch

CountDownLatch一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

再CountDownLatch中两个比较关键的方法:

public void await() throws InterruptedException;
public void countDown();

CountDownLatch是一个计数器,它的构造方法中需要设置一个数值,用来设定计数的次数。每次调用countDown()方法之后,这个计数器都会减去1,CountDownLatch会一直阻塞着调用await()方法的线程,直到计数器的值变为0

设想有这样一个功能需要Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给主线程去做汇总,利用CountDownLatch来完成就非常轻松。

public class CountDownLatchTest {private static CountDownLatch count = new CountDownLatch(4);private static ExecutorService service = Executors.newFixedThreadPool(6);public static void main(String args[]) throws InterruptedException {for (int i = 0; i < 4; i++) {service.execute(() -> {// 模拟任务耗时try {int timer = new Random().nextInt(5);TimeUnit.SECONDS.sleep(timer);System.out.printf("%s时完成磁盘的统计任务,耗费%d秒.\n", new Date().toString(), timer);// 任务完成之后,计数器减一count.countDown();} catch (InterruptedException e) {e.printStackTrace();}});}// 主线程一直被阻塞,知道count的计数器被设置为0count.await();System.out.printf("%s时全部任务都完成,执行合并计算.\n", new Date().toString());service.shutdown();}
}

CyclicBarrier

Barrier在英语中是屏障的意思,这个同步工具会阻塞调用的线程,直到条件满足时,阻塞的线程同时被打开。

public int await() throws InterruptedException, BrokenBarrierException

CyclicBarrier初始化的时候,设置一个屏障数。线程调用await()方法的时候,这个线程就会被阻塞,当调用await()的线程数量到达屏障数的时候,主线程就会取消所有被阻塞线程的状态。

CyclicBarrier的构造方法中,还可以设置一个barrierAction

在所有的屏障都到达之后,会启动一个线程来运行这里面的代码。这里举一个例子:百米赛跑的运动员起跑前需要准备,所有选手准备完毕之后,才可以同时起跑。

public class CyclicBarrierTest {private static CyclicBarrier cyclicBarrier = new CyclicBarrier(8);private static ExecutorService service = Executors.newFixedThreadPool(50);public static void main(String args[]) {for (int i = 1; i < 9; i++) {service.execute(new Thread(new Runner(i, cyclicBarrier)));}service.shutdown();}
}
// 运动员类
public class Runner implements Runnable {private int number;private CyclicBarrier cyclicBarrier;public Runner(int number, CyclicBarrier cyclicBarrier) {this.number = number;this.cyclicBarrier = cyclicBarrier;}@Overridepublic void run() {try {int timer = new Random().nextInt(5);TimeUnit.SECONDS.sleep(timer);System.out.printf("%d号选手准备完毕,准备时间%d\n", number, timer);cyclicBarrier.await();System.out.printf("%d号选手于%s时起跑!\n", number, new Date().toString());} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}
}

输出:

1号选手准备完毕,准备时间0
4号选手准备完毕,准备时间0
5号选手准备完毕,准备时间1
8号选手准备完毕,准备时间1
3号选手准备完毕,准备时间2
2号选手准备完毕,准备时间3
7号选手准备完毕,准备时间3
6号选手准备完毕,准备时间3
7号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
2号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
5号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
6号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
3号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
8号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
4号选手于Sun Mar 27 21:19:00 CST 2016时起跑!
1号选手于Sun Mar 27 21:19:00 CST 2016时起跑!

相比CountDownLatchCyclicBarrier是可以被循环使用的,而且遇到线程中断等情况时,还可以利用reset()方法,重置计数器,从这些方面来说,CyclicBarrier会比CountDownLatch更加灵活一些。

Semaphore

Semaphore被用于控制特定资源在同一个时间被访问的个数。类似连接池的概念,保证资源可以被合理的使用。

Semaphore的几个重要方法:

// 获取资源
public void acquire() throws InterruptedException
// 释放资源
public void release()

Semaphore的构造方法可以设置一个int值来设置一个计数器,用于表示资源同时可以被多少外部环境使用。每使用一次acquire(),计数器都会去减去一,而每次调用release()计数器则会增加一。当计数器的值为0的时候,外部的环境被阻塞,直到Semaphore有空闲的资源可以被使用。

public class SemaphoreTest {private static Semaphore semaphore = new Semaphore(3);private static ExecutorService service = Executors.newFixedThreadPool(6);public static void main(String args[]) {// 执行9个任务for (int i = 0; i < 9; i++) {service.execute(() -> {try {semaphore.acquire();System.out.printf("%s时获取资源,并调用.\n", new Date().toString());// 线程挂起3秒TimeUnit.SECONDS.sleep(3);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}});}service.shutdown();}
}

运行的结果就是:

Sun Mar 27 20:18:16 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:16 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:16 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:19 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:19 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:19 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:22 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:22 CST 2016时获取资源,并调用.
Sun Mar 27 20:18:22 CST 2016时获取资源,并调用.

虽然线程池允许6个最大线程数量,但是同一个时间内只用三个任务被执行。

转载于:https://www.cnblogs.com/whthomas/p/java_concurrent_tools.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS图片拉伸技巧

纵观移动市场&#xff0c;一款移动app&#xff0c;要想长期在移动市场立足&#xff0c;最起码要包含以下几个要素&#xff1a;实用的功能、极强的用户体验、华丽简洁的外观。华丽外观的背后&#xff0c;少不了美工的辛苦设计&#xff0c;但如果开发人员不懂得怎么合理展示这些设…

LeetCode 2341. 数组能形成多少数对

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的整数数组 nums 。在一步操作中&#xff0c;你可以执行以下步骤&#xff1a; 从 nums 选出 两个 相等的 整数从 nums 中移除这两个整数&#xff0c;形成一个 数对 请你在 nums 上多次执行此操作直到无法继续执行。 返…

三、MyBatis 使用传统 Dao 开发方式

1.0 使用 Dao 的实现类,操作数据库 1.0.1 Dao 开发 &#xff08;0&#xff09;定义接口StudentDao 及创建接口的映射文件StudentDao .xm package com.zep.dao;import com.zep.domain.Student;import java.util.List;public interface StudentDao {List<Student> selec…

Spring MVC控制器用@ResponseBody声明返回json数据报406的问题

本打算今天早点下班&#xff0c;结果下午测试调试程序发现一个问题纠结到晚上才解决&#xff0c;现在写一篇博客来总结下。 是这样的&#xff0c;本人在Spring mvc控制层用到了ResponseBody标注&#xff0c;以便返回的数据为json格式的数据&#xff0c;到前端JS中用。 问题来了…

LeetCode 2347. 最好的扑克手牌

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 ranks 和一个字符数组 suit 。你有 5 张扑克牌&#xff0c;第 i 张牌大小为 ranks[i] &#xff0c;花色为 suits[i] 。 下述是从好到坏你可能持有的 手牌类型 &#xff1a; "Flush"&#xff1a;同花&#xff0c;五…

四、MyBatis 框架 Dao 动态代理

1.1 步骤 &#xff08;1&#xff09; 去掉 之前编写的Dao 接口实现类 &#xff08;2&#xff09; getMapper 获取代理对象 只需调用 SqlSession 的 getMapper()方法&#xff0c;即可获取指定接口的实现类对象。该方法的参数为指定 Dao接口类的 class 值。 不使用工具类&…

C++中的常量折叠

先看例子&#xff1a; #include <iostream> using namespace std; int main() { const int a 10; int * p (int *)(&a); *p 20; cout<<"a "<<a<<", *p "<<*p<<endl; return 0; } 输出&#xff1a;a 10&…

五、深入理解Mybatis中的参数parameterType (传递一个简单参数,传递多个参数:@Param、使用自定义对象、按位置、使用Map)

1.1 parameterType parameterType: 接口中方法参数的类型&#xff0c; 类型的完全限定名或别名。这个属性是可选的&#xff0c;因为 MyBatis可以推断出具体传入语句的参数&#xff0c;默认值为未设置&#xff08;unset&#xff09;。接口中方法的参数从 java 代码传入到mapper…

React: JSX 、虚拟 DOM、组件配置(props、state、PropTypes、createContext、props.children)

文章目录1. 虚拟 DOM2. JSX3. ReactComponent4. props 是参数5. PropTypes6. getDefaultProps() 获取默认 props7. 上下文8. 多个上下文9. state在setState中使用函数&#xff0c;而不是对象10. 无状态组件11. 使用 props.children 与子组件对话learn from 《React全家桶&#…

android客户端在多个界面切换时保持socket的链接的实例

鉴于自己的痛苦&#xff0c;研究一个socket在多个界面切换时保持链接的问题&#xff0c;令我纠结很久&#xff0c;现在我提供客户端的源码给有需要的人参考。 1、ApplicationUtil类&#xff1a; import java.io.DataInputStream; import java.io.DataOutputStream; import java…

六、封装 MyBatis 输出结果resultType、resultMap 以及 数据库表中列名和返回对象属性名不一致的2种解决方案(详解)

1.1 resultType resultType: 执行 sql 得到 ResultSet 转换的类型&#xff0c;使用类型的完全限定名或别名。 注意&#xff1a;如果返回的是集合&#xff0c;那应该设置为集合包含的类型&#xff0c;而不是集合本身。resultType 和 resultMap&#xff0c;不能同时使用。 A、…

API 接口批量测试

ApiPost 创建接口 导入要测试的数据 测试结果 ApiFox 创建接口 导入接口 导入测试数据&#xff0c;可以直接编辑&#xff0c;粘贴进来 测试结果

LeetCode 2342. 数位和相等数对的最大和

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的数组 nums &#xff0c;数组中的元素都是 正 整数。请你选出两个下标 i 和 j&#xff08;i ! j&#xff09;&#xff0c;且 nums[i] 的数位和 与 nums[j] 的数位和相等。 请你找出所有满足条件的下标 i 和 j &#xff…

软件项目管理-构建之法-四周总结

写在前面 课程名&#xff1a;软件项目管理 授课人&#xff1a;东北师范大学 杨贵福&#xff08; http://www.cnblogs.com/younggift/&#xff09; 教材&#xff1a;《构建之法 - 现代软件工程》 作者&#xff1a;邹欣老师 &#xff08;博客&#xff1a;http://www.cnblogs.com…

一、Vue基础语法学习笔记系列——插值操作(Mustache语法、v-once、v-html、v-text、v-pre、v-cloak)、绑定属性v-bind(绑定class、style)、计算属性

一、插值操作 1. Mustache 如何将data中的文本数据&#xff0c;插入到HTML中呢&#xff1f; 我们已经学习过了&#xff0c;可以通过Mustache语法(也就是双大括号)。 Mustache: 胡子/胡须. 我们可以像下面这样来使用&#xff0c;并且数据是响应式的 2. v-once 但是&#xff0…

LeetCode 2348. 全 0 子数组的数目

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 nums &#xff0c;返回全部为 0 的 子数组 数目。 子数组 是一个数组中一段连续非空元素组成的序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,3,0,0,2,0,0,4] 输出&#xff1a;6 解释&#xff1a; 子数组 [0] 出现了…

二、Vue基础语法学习笔记——事件监听v-on、条件判断(v-if、v-else-if、v-else、v-show)、循环遍历(v-for遍历数组对象,key属性、检测数组更新)、图书案例、双向绑定

四、事件监听 在前端开发中&#xff0c;我们需要经常和用于交互。 这个时候&#xff0c;我们就必须监听用户发生的时间&#xff0c;比如点击、拖拽、键盘事件等等 在Vue中如何监听事件呢&#xff1f;使用v-on指令 v-on介绍 作用&#xff1a;绑定事件监听器 缩写&#xff1a; 预…

HDU4859 海岸线(最小割)

题目大概就是说一个n*m的地图&#xff0c;地图上每一块是陆地或浅海域或深海域&#xff0c;可以填充若干个浅海域使其变为陆地&#xff0c;问能得到的最长的陆地海岸线是多少。 也是很有意思的一道题。 一开始想歪了&#xff0c;想着&#xff0c;不考虑海岸线重合的情况那海岸线…

LeetCode 2352. 相等行列对

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid &#xff0c;返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和列以相同的顺序包含相同的元素&#xff08;即相等的数组&#xff09;&#xff0c;则认为二者是相等的。 示…

JAVA电话本系统

package com.sunhang.phonebook; import java.text.ParseException;import java.util.ArrayList;import java.util.List;import java.util.Scanner; public class PhoneBook { //存放联系人的容器 List<Contacts> list new ArrayList<Contacts>(); /** * 增加联系…