网站首页 > 博客文章 正文
Java并发包 JUC 是 在Java 5.0添加的 java.util.concurrent 包的简称,目的就是为了更好地支持高并发任务,让开发者进行多线程编程时可以有效地减少竞争条件和死锁线程。JUC一直也是Java面试中常考的内容,本文将JUC包的内容梳理一下。
JUC包的组成
JUC包主要包括5个部分:工具类(tools)、线程池类(Executor)、原子操作类(Atomic)、锁类(Locks)、并发容器类(Collections)。
工具类
工具类主要包括:闭锁(CountDownLatch)、栅栏(CyclicBarrier)和信号量(Semaphone)、线程池工厂类(Executors)、交换器(Exchanger)。
(1)CountDownLatch 是一个同步辅助类,CountDown的意思是倒计数,Latch的意思是门闩(shuan一声)。这个工具用来控制线程等待,让某一个线程等待直到倒计数结束再开始执行。常用在线程需要等待一组操作完成之后才能执行的场景中。
(2)CyclicBarrier 也是线程并发控制工具,Barrier的意思是栅(zha四声)栏,作用是阻止线程继续执行,要求线程在栅栏外等待。CyclicBarrier 让一组线程互相等待,直到所有线程都到达某个公共屏障点 ,才继续执行。
(3)Semaphore 是一个计数信号量,它的本质是一个“共享锁“。信号量维护了一个信号量许可集。线程可以通过调用 acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。
(4)Executors 主要是用来创建线程池。
阿里巴巴Java开发手册中明确指出:不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式是让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
(5)Exchanger 用于两个线程交换对象,一个线程负责生产对象,另一个线程负责消费对象。实际当中用得比较少。
线程池类
Java1.5引入的Executor框架实现的是线程池的功能,实现了工作单元(任务)和任务执行分离。Executor框架主要包括3大部分:
(1)任务,即工作单元。执行任务需要实现的接口是 Runnable 接口(无返回值)或者 Callable 接口(有返回值);
(2)任务的执行。把任务分派给多个线程的执行机制,包括 Executor 接口及继承自 Executor 接口的 ExecutorService 接口。
(3)异步任务。包括 Future 接口及实现了 Future 接口的 FutureTask 类。
Executor 是线程池的顶级接口,但它只有一个执行线程的方法 execute(),主要的线程池接口是 ExecutorService。
ExecutorService接口的实现类有两个:
(1)ThreadPoolExecutor 是线程池的具体实现,用来执行被提交的任务,包括Runnable任务或者 Callable 任务。
(2)ScheduledThreadPoolExecutor 继承了 ThreadPoolExecutor 并实现了 ScheduledExecutorService 接口。主要用于在给定的延迟后执行任务或者定期执行任务。
关于线程池类ThreadPoolExecutor 可以参考前文《Java面试必考问题:Tomcat为啥不用Java原生线程池 》。
原子操作类
JDK提供的一组原子操作类,实现原理大多是内部持有类型变量value,而且变量被volatile关键字修饰。这样保证每次线程使用变量的时候,都会拿到最新的值。
当多个线程同时对原子类型变量的值进行更新时,仅有一个线程能成功,而未成功的线程可以像自旋锁一样,继续尝试,一直等到执行成功。
java.util.concurrent.atomic 包中共有12个类:
- 原子类型:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
- 原子数组类型:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
- 原子属性更新器:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
- 解决 ABA 问题的原子类型:AtomicMarkableReference,AtomicStampedReference
关于ABA问题的介绍,可以参考前文《Java面试必考问题:如何解决CAS算法的ABA问题 》。
锁类
Locks 包(java.util.concurrent.locks)是JDK提供的锁机制,相比 synchronized 关键字,Locks包提供的框架功能更加强大,允许开发者更灵活地使用锁。
主要的实现类包括:
(1)可重入锁 ReentrantLock:ReentrantLock是独占锁,是指只能被独自占领,即同一个时间点只能被一个线程锁获取到的锁。
(2)可重入读写锁 ReentrantReadWriteLock:它包括两个内部类 ReadLock 和 WriteLock 。ReadLock是共享锁,而WriteLock是独占锁。
(3)线程阻塞工具类 LockSupport:具备阻塞线程和解除阻塞线程的功能,并且不会引发死锁。
关于可重入锁的介绍,可参考前文《Java编程必考问题:什么是ReentrantLock? 》。
并发容器类
主要是提供线程安全的容器。大部分常用的Java集合类(Set、List和Map)都不是线程安全的,不过一般都有对应的线程安全的并发容器类,比如:
(1)ArrayList 对应的并发容器类是 CopyOnWriteArrayList;
(2)HashSet 对应的并发容器类是 CopyOnWriteArraySet;
(3)HashMap 对应的并发容器类是 ConcurrentHashMap。
我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,欢迎大家关注,谢谢。
- 上一篇: 揭开「拓扑排序」的神秘面纱
- 下一篇: Java性能优化神器,一文读懂Java并发工具
猜你喜欢
- 2025-01-01 第一篇|Spark概览
- 2025-01-01 蔚来真题和答案,主打一个简单?
- 2025-01-01 ABB工业机器人编程指令函数程序数据等
- 2025-01-01 eNodeB启动和RRC连接建立
- 2025-01-01 硬盘SMART检测参数详解
- 2025-01-01 富集分析,看完这篇就够
- 2025-01-01 18个并发场景的设计模式详解,有没有你的盲区
- 2025-01-01 并发编程常见问题
- 2025-01-01 阿里架构师亲自梳理的:多线程与高并发知识点
- 2025-01-01 应读者要求讲讲 DMA
你 发表评论:
欢迎- 最近发表
-
- 告别频繁登录!Nuxt3 + TS + Vue3实战:双Token无感刷新方案全解析
- SpringBoot实现单点登录(SSO)的4种方案
- 随机密聊 匿名聊天室程序源码(随机匿名聊天在线)
- SpringBoot大文件上传卡死?分块切割术搞定GB级传输,速度飙升!
- Java 微服务从源码实战开始 | Gitee 项目推荐
- 轻量级埋点sdk搭建,便捷更全面(埋点sdk是什么)
- Spring Boot 实现文件秒传功能(springboot上传文件到指定文件夹)
- 项目中不用redis分布式锁,怎么防止用户重复提交?
- SpringBoot项目日志打印traceId生成
- 如何实现PC端网站扫码登录操作?(网页 扫码)
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- flutterrun (59)
- 系统设计图 (58)
- powershellfor (73)
- messagesource (71)
- plsql64位 (73)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- qcombobox样式表 (68)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)