【JAVAEE】JUC(java.util.concurrent)的常见类
目录
1.Callable接口
1.1简介
1.2代码演示
1.3Runnable与Callable的区别
2.ReentrantLock
2.1ReentrantLock的常用方法
2.2ReentrantLock的代码演示
2.3ReentrantLock和synchronized的区别
3.Semaphore信号量
3.1概念
3.2代码演示
4.CountDownLatch
4.1概念
4.2代码演示
JUC是java.util.concurrent包的简称,JDK1.5之后对多线程的一种实现,这个包下放的类都和多线程有关,提供了很多工具类。
1.Callable接口
1.1简介
Callable是一个interface。相当于把线程封装了一个“返回值”,方便程序员借助多线程的方式计算得出结果。
Callable是创建线程的一种的方式,与Runnable类似。
当你的任务需要返回值时,用Callable比较好。
1.2代码演示
先定义一个线程的任务(从1加到10的结果)
public static void main(String[] args) {//先定义一个线程的任务Callable<Integer>callable=new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum=0;for (int i = 0; i < 10; i++) {sum+=i;}return sum;}};}
使用FutureTask类来创建一个对象,这个对象持有callable。执行任务并获取结果。
(FutureTask是Runnable的一个实现类,所以可以传入Thread的构造方法中)
//通过FutureTask类来创建一个对象,这个对象持有callableFutureTask<Integer>futureTask=new FutureTask<>(callable);//创建线程并指定任务Thread thread=new Thread(futureTask);//让线程执行定义好的任务thread.start();//获取线程执行的结果Integer result=futureTask.get();//打印结果System.out.println(result);
实现结果:
1.3Runnable与Callable的区别
如上图所示:
①Callable实现的是Call方法,Runnable实现的是Run方法
②Callable可以返回一个结果,Runnable不能返回结果
③Callable要配合FutureTask一起使用
④Callable可以抛出异常,Runnable不可以
2.ReentrantLock
可重入互斥锁,和synchronized定位类似,都是用来实现互斥效果,保证线程安全。是基于CAS实现的一个纯用户态的锁。
2.1ReentrantLock的常用方法
常用方法:
lock():加锁,如果获取不到锁就死等
trylock():尝试加锁
unlock():解锁
常用方法的使用代码演示:
public static void main(String[] args) throws InterruptedException {//创建一个ReentrantLock锁对象ReentrantLock reentrantLock=new ReentrantLock();//加锁reentrantLock.lock();//尝试加锁,死等reentrantLock.tryLock();//尝试加锁,有超时时间reentrantLock.tryLock(1, TimeUnit.SECONDS);//释放锁reentrantLock.unlock();}
2.2ReentrantLock的代码演示
模拟业务中出现异常情况时,如何释放锁:
//模拟业务中如果出现异常情况,如何释放锁public static void Demo02() throws Exception {//创建一个ReentrantLock锁对象ReentrantLock reentrantLock=new ReentrantLock();try {//加锁reentrantLock.lock();//TODO:业务逻辑throw new Exception("业务出现异常");}finally {//保证出现异常的时候也可以释放锁reentrantLock.unlock();}}
演示创建一个公平锁(默认为false):
//演示创建一个公平锁public static void demo03(){//创建一个ReentrantLock锁对象,通过构造方法,传入true时为公平锁,默认为falseReentrantLock reentrantLock=new ReentrantLock(true);}
演示创建一个读写锁:
//演示创建一个读写锁public static void demo04(){//创建ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();//获取读锁,共享锁,读与读可以同时进行readWriteLock.readLock();//获取写锁,排他锁(互斥锁),读写,写读,写写都不能共存readWriteLock.writeLock();}
ReentrantLock可以根据不同的Condition去休眠或唤醒线程。
演示:
两个条件:1.只处理男生任务
2.只处理女生任务
private static ReentrantLock reentrantLock=new ReentrantLock();//定义不同的条件private static Condition boyCondition = reentrantLock.newCondition();private static Condition girlCondition = reentrantLock.newCondition();public static void demo05() throws InterruptedException {Thread threadBoy = new Thread(() -> {// 让处理男生任务的线程去休眠try {boyCondition.await();} catch (InterruptedException e) {e.printStackTrace();}// 唤醒处理女生任务的线程girlCondition.signalAll();});Thread threadGirl = new Thread(() -> {// 让处理女生任务的线程去休眠try {girlCondition.await();} catch (InterruptedException e) {e.printStackTrace();}// 唤醒处理男生任务的线程boyCondition.signalAll();});}
2.3ReentrantLock和synchronized的区别
区别:
①synchronized使用时不需要手动释放锁,ReentrantLock使用时需要手动释放,使用起来更灵活,但是也容易遗漏unlock
②sychronized在申请锁失败时,会一直等待锁资源,ReentrantLock可以通过trylock的方式等待一段时间就放弃
③synchronized是非公平锁,ReentrantLock默认是非公平锁。可以通过构造方法传入一个true开启公平锁模式
④synchronized是一个关键字,是JVM内部实现的,ReentrantLock是标准库的一个类,基于Java JUC实现
3.Semaphore信号量
3.1概念
信号量,用来表示“可用资源的个数”。本质上就是一个计数器。
理解信号量:
停车场外的显示屏上通常会显示当前停车场李可用的车位个数,车位个数相当于是可用资源。
1.当一辆车入场后,相当于申请一个资源,车位的个数就减一(这个称为信号量的 P 操作)
2.当一辆车离开时,相当于释放一个资源,车位的个数就加一(这个称为信号量的 V 操作)
3.停车场所有的车位就是可以显示的最大有效值
申请资源的时候,当资源已经被用完,那么线程申请的时候就会阻塞等待。
补充:当代码需要指定有限的资源个数时,可以考虑使用Semaphore来处理。
3.2代码演示
定义一个信号量,指定可用资源个数为3
//定义一个信号量,指定可用资源个数private static Semaphore semaphore=new Semaphore(3);
模拟业务处理
public static void main(String[] args) {//定义一个任务Runnable runnable=new Runnable() {@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName()+"[+]申请资源");//调用此方法,可用资源数减一semaphore.acquire();System.out.println(Thread.currentThread().getName()+"[!]申请到资源");//模拟业务处理TimeUnit.SECONDS.sleep(1);//释放资源semaphore.release();System.out.println(Thread.currentThread().getName()+"[-]释放了资源");} catch (InterruptedException e) {throw new RuntimeException(e);}}};//创建多个线程for (int i = 0; i < 20; i++) {Thread thread=new Thread(runnable);thread.start();}}
当申请资源满了时,就会阻塞等待。
4.CountDownLatch
4.1概念
同时等待N个任务执行结束。
理解CountDownLatch:
好像跑步比赛,10个选手依次就位,哨声响起才同时出发,所有选手都通过终点,才能结束比赛。
作用:可以设置所有的线程必须都到达某一个关键点然后再执行后续的操作。
4.2代码演示
演示跑步比赛:
定义一个CountDownLatch,参数为10代表10个选手
//定义一个CountDownLatchprivate static CountDownLatch countDownLatch=new CountDownLatch(10);
创建线程,模拟10个选手比赛,直到10个选手都到达终点才会颁奖
public static void main(String[] args) throws InterruptedException {System.out.println("所有选手各就各位");//创建线程,模拟跑步比赛for (int i = 0; i < 10; i++) {Thread thread=new Thread(()->{System.out.println(Thread.currentThread().getName()+"出发");//模拟比赛过程try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}//到达终点,计数减一countDownLatch.countDown();System.out.println(Thread.currentThread().getName()+"到达终点");},"player"+(i+1));thread.start();}//等待所有线程执行完成//一直等到countDownLatch为0时才会执行之后的代码countDownLatch.await();//颁奖System.out.println("开始颁奖");}
运行结果:
【JAVAEE】JUC(java.util.concurrent)的常见类相关推荐
- JUC(java.util.concurrent)的常见类
文章目录 一.JUC常见类 Callable 接口 ReentrantLock Semaphore(信号量) CountDownLatch 一.JUC常见类 concurrent代表了并发,这个包下为 ...
- 高并发编程基础(java.util.concurrent包常见类基础)
JDK5中添加了新的java.util.concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法 ...
- java.util.concurrent.atomic原子操作类包
2019独角兽企业重金招聘Python工程师标准>>> 这个包里面提供了一组原子变量类.其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当 ...
- juc java_深入理解JUC(java.util.concurrent)
Concurrent下的核心类 Executor:具有runnable任务的执行者 ExecutorService:一个线程池管理者,实现类有多种,能把runnable,callable提交到线程池中 ...
- 【JDK源码】java.util.concurrent.atomic包常用类详解
java.util.concurrent.atomic原子操作类包里面提供了一组原子变量类.其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方 ...
- 关于 java.util.concurrent 您不知道的 5 件事--转
第 1 部分 http://www.ibm.com/developerworks/cn/java/j-5things4.html Concurrent Collections 是 Java™ 5 的巨 ...
- java.util.concurrent同步框架(AQS论文中文翻译)
java.util.concurrent同步框架 摘要 目录和主题描述 一般条款 关键字 1.介绍: 需求 设计实现 4.使用方式 5.性能 6.结论 7. 致谢 Doug Lea SUNY Oswe ...
- 【ArrayList】为什么java.util.concurrent 包里没有并发的ArrayList实现?
2019独角兽企业重金招聘Python工程师标准>>> 为什么java.util.concurrent 包里没有并发的ArrayList实现? 问:JDK 5在java.util.c ...
- Java 理论与实践: 流行的原子——新原子类是 java.util.concurrent 的隐藏精华(转载)...
简介: 在 JDK 5.0 之前,如果不使用本机代码,就不能用 Java 语言编写无等待.无锁定的算法.在 java.util.concurrent 中添加原子变量类之后,这种情况发生了变化.请跟随并 ...
最新文章
- underscore.js _.initial[Array]
- 微软MSDN中文网络广播(Webcast)——Visual Studio 2010 ALM应用实践系列课程预告(2011)...
- 利用ASP .NET Core的静态文件原理实现远程访问Nlog日志内容及解决遇到的坑
- 机器学习笔记(六):正则化
- php列出mysql表格,php列出mysql表所有行和列的方法
- java解析xml串标签_Java反射解析XML字符串并封装到指定的JavaBean
- 引物设计软件primer_PCR-引物设计原则
- 关于sources.list和apt-get [转载]
- linux查看文件权限_Linux权限管理 -- 文件权限
- Machine learning approximation algorithmsfor high-dimensional fully nonlinear PDE
- c语言太极图编程语言,C语言画图之 画个太极图
- Google 的浏览器安全手册
- 华为al00的计算机在哪,(详细)华为畅享8 LDN-AL00的USB调试模式在哪里开启的流程...
- 吃糖果 (HDU-1205)(鸽笼原理(抽屉原理))
- 设计师Adobe国际认证证书有用吗?
- 平均差误法中存在哪些误差?如何平衡这些误差?|小白心理-312/347考研答疑
- 农历php,PHP阴历转农历的实现代码
- [Go] String型常用操作
- 1.7-秩和相关关系
- JDBC简介及原理和使用介绍
热门文章
- 计算机技术职称自我评价,网络工程师的自我评价
- cta计算机,2.5 CTA:一种实际的并行计算机模型
- 阿里巴巴离职DBA在35岁总结的职业生涯(转)
- 苹果svg解析自适应长图
- 模拟电路设计(40)---你真的懂“接地”吗?
- h5背景图片尺寸怎么设置_CSS3中background-size实现背景图片大小可自定义的几种效果(代码实例 )...
- Springboot使用s7connector 实现对西门子PLC数据读写
- Git强拉远程代码覆盖本地代码
- python实现天气预报_【Python3爬虫】用Python实现发送天气预报邮件
- 沪深A股分析数据投资参考信息API接口(JSON标准格式,Get请求方式)