JVM中的锁机制有哪些?如何选择合适的锁?
困难JVM锁机制
💬0
🔥0
👍0
详细说明JVM中的各种锁机制,包括synchronized、ReentrantLock、ReadWriteLock等,以及锁的选择策略
参考答案
JVM提供了多种锁机制来保证多线程程序的正确性,每种锁都有其适用场景:
- synchronized关键字
基本用法
public class SynchronizedExample {
// 实例方法同步
public synchronized void method1() {
// 临界区代码
}
// 静态方法同步
public static synchronized void method2() {
// 临界区代码
}
// 代码块同步
public void method3() {
synchronized (this) {
// 临界区代码
}
}
}
实现原理
- 对象头:Mark Word存储锁信息
- 监视器:每个对象关联一个监视器
- 锁升级:偏向锁→轻量级锁→重量级锁
特点
- 自动加锁和释放
- 可重入
- 非公平锁
- 性能相对较低
- ReentrantLock
基本用法
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void method() {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}
}
高级特性
public class AdvancedLockExample {
private final ReentrantLock lock = new ReentrantLock(true); // 公平锁
private final Condition condition = lock.newCondition();
public void await() throws InterruptedException {
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}
public void signal() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
特点
- 手动加锁和释放
- 支持公平锁和非公平锁
- 支持条件变量
- 性能相对较高
- ReadWriteLock
基本用法
public class ReadWriteLockExample {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
private Map<String, Object> cache = new HashMap<>();
public Object get(String key) {
readLock.lock();
try {
return cache.get(key);
} finally {
readLock.unlock();
}
}
public void put(String key, Object value) {
writeLock.lock();
try {
cache.put(key, value);
} finally {
writeLock.unlock();
}
}
}
特点
- 读锁共享,写锁独占
- 适合读多写少的场景
- 提高并发性能
- 避免写饥饿
- StampedLock
基本用法
public class StampedLockExample {
private final StampedLock lock = new StampedLock();
private double x, y;
public void move(double deltaX, double deltaY) {
long stamp = lock.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
lock.unlockWrite(stamp);
}
}
public double distanceFromOrigin() {
long stamp = lock.tryOptimisticRead();
double currentX = x, currentY = y;
if (!lock.validate(stamp)) {
stamp = lock.readLock();
try {
currentX = x;
currentY = y;
} finally {
lock.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
}
特点
- 支持乐观读锁
- 性能最高
- 不支持条件变量
- 适合读多写少的场景
- 锁的选择策略
性能考虑
- 低竞争:synchronized
- 中等竞争:ReentrantLock
- 高竞争:StampedLock
功能需求
- 需要条件变量:ReentrantLock
- 读多写少:ReadWriteLock或StampedLock
- 简单同步:synchronized
公平性要求
- 公平锁:ReentrantLock(true)
- 非公平锁:synchronized或ReentrantLock(false)
- 锁的性能优化
减少锁竞争
public class OptimizedLockExample {
// 使用分段锁减少竞争
private final Lock[] locks = new Lock[16];
private final Map<String, Object>[] maps = new Map[16];
public OptimizedLockExample() {
for (int i = 0; i < 16; i++) {
locks[i] = new ReentrantLock();
maps[i] = new HashMap<>();
}
}
public Object get(String key) {
int index = key.hashCode() % 16;
locks[index].lock();
try {
return maps[index].get(key);
} finally {
locks[index].unlock();
}
}
}
锁的粒度控制
- 细粒度锁:减少竞争但增加复杂度
- 粗粒度锁:简单但可能影响性能
- 根据实际场景选择合适的粒度
评论区 (0)
暂无评论,来发表第一条评论吧!