ReentrantReadWriteLock使用
ReentrantReadWriteLock读写锁使用
先看一下读读操作
@Slf4j(topic = "c.TestReadWriteLock")
public class TestReadWriteLock {
public static void main(String[] args) throws InterruptedException {
DataContainer dataContainer = new DataContainer();
new Thread(() -> {
dataContainer.read();
}, "t1").start();
new Thread(() -> {
dataContainer.read();
}, "t2").start();
}
}
@Slf4j(topic = "c.DataContainer")
class DataContainer {
private Object data;
private ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock r = rw.readLock();
private ReentrantReadWriteLock.WriteLock w = rw.writeLock();
public Object read() {
log.debug("获取读锁...");
r.lock();
try {
log.debug("读取");
sleep(1);
return data;
} finally {
log.debug("释放读锁...");
r.unlock();
}
}
public void write() {
log.debug("获取写锁...");
w.lock();
try {
log.debug("写入");
sleep(1);
} finally {
log.debug("释放写锁...");
w.unlock();
}
}
}
运行结果
21:00:20.919 c.DataContainer [t2] - 获取读锁...
21:00:20.919 c.DataContainer [t1] - 获取读锁...
21:00:20.922 c.DataContainer [t2] - 读取
21:00:20.922 c.DataContainer [t1] - 读取
21:00:21.931 c.DataContainer [t1] - 释放读锁...
21:00:21.931 c.DataContainer [t2] - 释放读锁...
再来看一下读写
public static void main(String[] args) throws InterruptedException {
DataContainer dataContainer = new DataContainer();
new Thread(() -> {
dataContainer.read();
}, "t1").start();
Thread.sleep(100);
new Thread(() -> {
dataContainer.write();
}, "t2").start();
}
运行结果
21:03:31.173 c.DataContainer [t1] - 获取读锁...
21:03:31.175 c.DataContainer [t1] - 读取
21:03:31.272 c.DataContainer [t2] - 获取写锁...
21:03:32.176 c.DataContainer [t1] - 释放读锁...
21:03:32.176 c.DataContainer [t2] - 写入
21:03:33.176 c.DataContainer [t2] - 释放写锁...
注意事项
- 读锁不支持条件变量
- 重入时升级不支持:即持有读锁的情况下去获取写锁,会导致获取写锁永久等待
- 重入时降级支持:即持有写锁的情况下去获取读锁