获课:666it.top/6121/
Java并发高频考点:从synchronized到AQS深度解析
synchronized关键字原理与优化
synchronized是Java中最基础的同步机制,它解决的是多个线程之间访问资源的同步性问题,保证被修饰的方法或代码块在任意时刻只能有一个线程执行。
实现原理
通过JDK自带的javap命令查看字节码信息可以发现:
synchronized同步语句块使用monitorenter和monitorexit指令实现
monitorenter指令指向同步代码块的开始位置
monitorexit指令指向同步代码块的结束位置
任何对象都有一个monitor与之关联,当monitor被持有后,对象就会处于锁定状态
锁升级过程
偏向锁:第一次执行时,锁对象从无锁状态变成偏向锁(通过CAS修改对象头里的锁标志位)
轻量级锁:当有竞争时,偏向锁会升级为轻量级锁
重量级锁:轻量级锁竞争激烈时会进一步升级为重量级锁
优化方案
Java
// 基础同步方法
public synchronized void deductStock() {
if(stock > 0) stock--;
}
// 优化方案1:分段锁
class Bucket {
private int[] stocks = new int[16];
private ReentrantLock[] locks = new ReentrantLock[16];
public void deduct(int userId) {
int bucket = userId % 16;
locks[bucket].lock();
try {
if(stocks[bucket] > 0) stocks[bucket]--;
} finally {
locks[bucket].unlock();
}
}
}
AQS(AbstractQueuedSynchronizer)深度解析
AQS是Java并发包中的核心抽象类,为构建锁和同步器提供了框架基础。
AQS核心原理
状态管理:使用volatile变量state表示同步状态(锁是否占用)
队列管理:通过同步等待队列管理没有获取到同步状态的线程
独占模式:每次只能一个线程占用状态资源进行操作
AQS获取锁流程
Java
// 1.尝试获取锁
if(!tryAcquire(arg)) {
// 2.获取失败则加入队列
node = addWaiter(Node.EXCLUSIVE);
// 3.自旋获取锁或阻塞
acquireQueued(node, arg);
}
AQS实现类
基于AQS实现的三大利器:
CountDownLatch:允许一个或多个线程等待其他线程完成操作
CyclicBarrier:让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障
Semaphore:控制同时访问特定资源的线程数量
并发编程高频面试题解析
synchronized相关问题
synchronized与ReentrantLock区别:
synchronized是关键字,ReentrantLock是类
synchronized不可中断,ReentrantLock可中断
synchronized自动释放锁,ReentrantLock需要手动释放
ReentrantLock可以实现公平锁
悲观锁与乐观锁:
悲观锁:synchronized和Lock接口,认为并发冲突概率高
乐观锁:CAS机制,认为并发冲突概率低
volatile关键字:
保证可见性:一个线程修改后其他线程立即可见
禁止指令重排序
不保证原子性
AQS相关问题
AQS核心思想:
原子式管理同步状态
阻塞和唤醒线程功能
队列模型管理等待线程
AQS实现原理:
通过内置的FIFO双向队列完成线程排队
通过CAS操作实现状态修改
模板方法模式定义获取/释放锁的流程
AQS应用场景:
构建自定义同步器
实现各种并发工具类
解决复杂同步问题
高并发场景优化策略
减少锁粒度:使用分段锁或细粒度锁
减少锁持有时间:只在必要代码段加锁
读写分离:使用ReadWriteLock
无锁编程:使用CAS或原子类
线程池优化:合理配置线程池参数
理解synchronized和AQS的原理及使用场景,是Java并发编程的核心基础,也是面试中的高频考点。掌握这些知识不仅能帮助应对面试,更能提升实际开发中的并发编程能力。
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传