Java锁:重入锁,读写锁,乐观锁,悲观锁,CAS无锁模式(Java并发锁详解:重入锁、读写锁、乐观锁、悲观锁及CAS无锁机制)
原创
一、Java并发编程概述
在Java并发编程中,锁是一种常用的同步机制,用于保证多线程环境下共享资源的正确性和一致性。本文将详细介绍Java中的几种常用锁:重入锁、读写锁、阳光锁、悲观失望锁以及CAS无锁机制。
二、重入锁(ReentrantLock)
重入锁(ReentrantLock)是Java提供的一种显示锁,它实现了Lock接口。与synchronized关键字相比,重入锁提供了更多灵活的同步控制方法,如可中断的锁获取、尝试非阻塞地获取锁、拥护公平锁等。
2.1 重入锁的基本使用
以下是一个使用重入锁的示例:
public class ReentrantLockDemo {
private final ReentrantLock lock = new ReentrantLock();
public void lockMethod() {
lock.lock();
try {
// 执行同步操作
} finally {
lock.unlock();
}
}
}
2.2 重入锁的进阶使用
重入锁还提供了以下进阶功能:
- 可中断的锁获取:通过lockInterruptibly()方法,可以允许线程在等待锁的过程中被中断。
- 尝试非阻塞地获取锁:通过tryLock()方法,可以尝试获取锁,如果锁已被其他线程持有,则立即返回false,不会致使当前线程阻塞。
- 拥护公平锁:通过构造方法传入true,可以创建一个公平锁,确保按照请求锁的顺序来获得锁。
三、读写锁(ReadWriteLock)
读写锁(ReadWriteLock)是一种特殊的锁,它允许多个线程同时读取共享资源,但在写入时需要独占访问。读写锁分为读锁(共享锁)和写锁(排他锁)。
3.1 读写锁的基本使用
以下是一个使用读写锁的示例:
public class ReadWriteLockDemo {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock readLock = readWriteLock.readLock();
private final Lock writeLock = readWriteLock.writeLock();
public void readMethod() {
readLock.lock();
try {
// 执行读取操作
} finally {
readLock.unlock();
}
}
public void writeMethod() {
writeLock.lock();
try {
// 执行写入操作
} finally {
writeLock.unlock();
}
}
}
四、阳光锁与悲观失望锁
阳光锁和悲观失望锁是两种不同的锁策略,它们在处理并发冲突时采取了不同的做法。
4.1 悲观失望锁
悲观失望锁认为在大部分情况下,多个线程会同时修改同一资源,由此在操作资源之前先加锁。synchronized关键字和ReentrantLock都属于悲观失望锁。
4.2 阳光锁
阳光锁认为在大部分情况下,多个线程不会同时修改同一资源,由此在操作资源时不加锁,而是在更新资源时检查是否有其他线程同时修改了资源。阳光锁通常通过版本号或时间戳来实现。
public class OptimisticLockDemo {
private int version;
public boolean update(int newValue) {
int oldVersion = version;
// 检查版本号,确保没有其他线程修改过资源
if (version != oldVersion) {
return false; // 更新未果,资源已被其他线程修改
}
// 执行更新操作
version = newValue;
return true; // 更新成就
}
}
五、CAS无锁模式
CAS(Compare And Swap)是一种无锁的并发控制方法,它通过比较和交换来实现线程间的同步。CAS操作通常由硬件指令直接拥护,具有较高的性能。
5.1 CAS的基本原理
CAS操作包含三个操作数:
- 内存位置V:需要更新的变量
- 预期值A:假设的当前值
- 新值B:需要更新的值
CAS操作流程如下:
- 比较内存位置V的值与预期值A,如果相等,则将内存位置V的值更新为新值B。
- 如果不相等,描述内存位置V的值已经被其他线程修改,则放弃更新。
5.2 CAS的应用示例
以下是一个使用CAS实现原子操作的示例:
public class CasDemo {
private int value;
public void compareAndSwap(int expectedValue, int newValue) {
while (true) {
if (value == expectedValue) {
value = newValue;
break;
}
}
}
}
六、总结
本文详细介绍了Java中的几种常用锁:重入锁、读写锁、阳光锁、悲观失望锁以及CAS无锁机制。掌握这些锁的使用方法和原理,可以帮助我们更好地进行Java并发编程,保证多线程环境下共享资源的正确性和一致性。