Java并发 aqs
AQS:AbstractQueuedSynchronizer
一、AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器。
二、原理:AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
原理图:
三、学习路线图。大量的应用在j.u.c下的各个基础类和工具栏,构成Java并发包的基础。
四、1、有一个重要的状态标志——state,该属性是一个int值,表示对象的当前状态。三个protected final的方法来改变state的值,分别是:getState、setState(int)、compareAndSetState(int, int)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | private volatile int state; /** * Returns the current value of synchronization state. * This operation has memory semantics of a {@code volatile} read. * @return current state value */ protected final int getState() { return state; } /** * Sets the value of synchronization state. * This operation has memory semantics of a {@code volatile} write. * @param newState the new state value */ protected final void setState( int newState) { state = newState; } |
2、AQS定义两种资源共享方式
-
Exclusive(独占):只有一个线程能执行,如ReentrantLock。又可分为公平锁和非公平锁:
- 公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
- 非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的
- Share(共享):多个线程可同时执行,如Semaphore/CountDownLatch。Semaphore、CountDownLatCh、 CyclicBarrier、ReadWriteLock 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // exclusive mode protected boolean tryAcquire( int arg) { throw new UnsupportedOperationException(); } protected boolean tryRelease( int arg) { throw new UnsupportedOperationException(); } // shared mode共享模式 protected int tryAcquireShared( int arg) { throw new UnsupportedOperationException(); } protected boolean tryReleaseShared( int arg) { throw new UnsupportedOperationException(); } |
3、用到了模板设计模式
五、同步工具类
CountDownLatch
倒数计时。是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public class CountDownLatchDemo implements Runnable { static final CountDownLatch latch = new CountDownLatch( 10 ); static final CountDownLatchDemo demo = new CountDownLatchDemo(); @Override public void run() { // 模拟检查任务 try { Thread.sleep( new Random().nextInt( 20 ) * 100 ); System.out.println( "check complete" ); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 计数减一 // 放在finally避免任务执行过程出现异常,导致countDown()不能被执行 latch.countDown(); } } public static void main(String[] args) throws InterruptedException { ExecutorService exec = Executors.newFixedThreadPool( 10 ); for ( int i = 0 ; i < 10 ; i++) { exec.submit(demo); } // 等待检查 latch.await(); // 发射火箭 System.out.println( "Fire!" ); // 关闭线程池 exec.shutdown(); } } |
Semaphore
synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。
不错的博文:https://blog.csdn.net/lxltmac/article/details/84871929
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· MQ 如何保证数据一致性?