返回
Java 并发编程之 ReentrantReadWriteLock(五)写锁获取和释放
后端
2023-12-28 18:54:00
前言
前面几篇文章介绍了读锁的加锁和解锁流程,内容较多比较复杂,写锁的流程相对就简单一些了,根据源码来看一下具体流程。
加锁
前面两步和 ReentrantLock 一样,通过 lock 方法进行加锁,然后调用 acquireWrite 方法,acquireWrite 方法的流程如下:
- 首先检查是否有线程持有写锁,如果有,则直接返回,让当前线程进入等待队列;
- 如果没有线程持有写锁,则检查是否有线程正在等待写锁,如果有,则让当前线程进入等待队列;
- 如果既没有线程持有写锁,也没有线程正在等待写锁,则直接获取写锁。
释放锁
释放写锁的流程很简单,只需要调用 unlockWrite 方法即可,unlockWrite 方法的流程如下:
- 首先检查是否有其他线程正在等待写锁,如果有,则唤醒这些线程;
- 然后释放写锁。
示例代码
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReentrantReadWriteLockDemo5 {
private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public static void main(String[] args) {
// 创建一个写线程
Thread writeThread = new Thread(() -> {
// 获取写锁
lock.writeLock().lock();
try {
// 模拟写操作
System.out.println(Thread.currentThread().getName() + " is writing...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放写锁
lock.writeLock().unlock();
}
});
// 创建一个读线程
Thread readThread = new Thread(() -> {
// 获取读锁
lock.readLock().lock();
try {
// 模拟读操作
System.out.println(Thread.currentThread().getName() + " is reading...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放读锁
lock.readLock().unlock();
}
});
// 启动写线程和读线程
writeThread.start();
readThread.start();
}
}
运行结果
Thread-0 is writing...
Thread-1 is reading...
从运行结果可以看出,写线程先获取到了写锁,然后读线程才获取到了读锁,这说明写锁是排斥读锁的。