ReadWriteLock允许多个读线程并发访问,写线程独占访问,适用于读多写少场景;其核心为ReentrantReadWriteLock实现,提供readLock()和writeLock(),遵循读读不互斥、读写互斥、写写互斥原则,支持锁降级与可重入,建议在finally中释放锁,可通过构造函数选择公平或非公平模式以平衡吞吐与饥饿问题。
Java中的
ReadWriteLock
是一种
同步机制
,允许多个读线程同时访问共享资源,但在写操作时独占访问。它的核心思想是:读和读不互斥,读和写互斥,写和写互斥。这种设计能提升高并发读场景下的性能。
ReadWriteLock接口简介
ReadWriteLock 是一个接口,位于
java.util.concurrent.locks
包中。它定义了两个方法:
Lock readLock()
:返回用于读操作的锁。
Lock writeLock()
:返回用于写操作的锁。
最常见的实现类是
ReentrantReadWriteLock
,支持可重入性和公平/非公平模式。
读锁与写锁的行为规则
ReadWriteLock 的行为遵循以下原则:
立即学习
“
Java免费学习笔记(深入)
”;
多个线程可以同时持有读锁(读读不互斥)。
写锁是独占的,同一时刻只能有一个线程持有写锁(写写互斥)。
当有线程持有写锁时,其他读线程必须等待(读写互斥)。
写锁可以降级为读锁(先写后读),但读锁不能升级为写锁。
基本使用示例
下面是一个使用 ReentrantReadWriteLock 的简单例子:
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
在这个例子中,多个线程调用
read()
可以并发执行,而
write()
操作会阻塞所有读和写操作,直到完成。
锁的获取与释放注意事项
使用 ReadWriteLock 时要注意以下几点:
读锁和写锁都必须显式释放,建议放在 finally 块中。
同一个线程在持有写锁时可以再次获取读锁(锁降级),但反过来不行。
避免死锁:不要在持有读锁时尝试获取写锁,否则可能造成永久阻塞。
支持可重入:持有写锁的线程可以重复获取写锁。
公平性与性能选择
ReentrantReadWriteLock 支持构造时指定是否使用公平模式:
非公平模式(默认):允许插队,吞吐量更高。
公平模式:按请求顺序分配锁,避免饥饿,但性能较低。
创建方式:
new ReentrantReadWriteLock(true); // 公平模式
new ReentrantReadWriteLock(false); // 非公平模式(默认)
基本上就这些。ReadWriteLock 在读多写少的场景下非常有用,比如缓存、配置管理等。正确使用能显著提升并发性能,但也需注意锁的粒度和避免不当的锁升级。
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SharedData {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private volatile int data = 0;
public int read() {
lock.readLock().lock();
try {
System.out.println("读取数据: " + data);
return data;
} finally {
lock.readLock().unlock();
}
}
public void write(int value) {
lock.writeLock().lock();
try {
System.out.println("写入数据: " + value);
data = value;
} finally {
lock.writeLock().unlock();
}
}
}
