关于读写锁,是一种改进的排他锁,也被称为共享排他锁,一次只允许一个线程对共享变量进行更新。允许多个线程同时读取共享变量。当一个线程对共享变量进行更新的时候其他线程都无法进行访问。
读写锁的功能是通过其扮演的两种角色一读锁(Read Lock)和写锁(Write Lock) 实现的,读线程在访问共享变量的时候必须持有相应读写锁的读锁。读锁是可以同时被多个线程持有的, 即读锁是共享的(Shared). 一个读线程持有一个读锁的 时候并不妨碍其他读线程获得该读锁。写线程在访问共享变批的时候必须持有相应读写锁 的写锁。写锁是排他的(Exclusive), 即一个线程持有写锁的时候其他线程无法获得相应锁的写锁或读锁。java.util.concurrent.locks.ReadWriteLock接口是对读写锁的抽象,其默认实现类是java.util.concurrent.locks.ReentrantReadWriteLock。
ReadWriteLock接口定义了两个方法:readLock()和writeLock() , 如图3-3所示,分别用千返回相应读写锁实例的读锁和写锁。 这两个方法的返回值类型都是 Lock,这并不是表示一个 ReadWriteLock接口实例对应两个锁, 而是代表一个ReadWriteLock接口实例可以充当两种角色。
与普通的排他锁(如内部锁和ReentrantLock)相比,读写锁在排他性方面比较弱(这是我们所期望的)。在原子性、 可见性和有序性保障方面,它所起到的作用与普通的排 锁是一致的。ReentrantReadWriteLock 所实现的读写锁是个可重入锁。 ReentrantReadWriteLock 支持锁的降级(Downgrade), 即一个线程持有读写锁的写锁的情况下可以继续获得相应的读锁.
代码实例:
public class ReadAndWriteLockTest {
private final ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
private final Lock readLock=readWriteLock.readLock();
private final Lock writeLock=readWriteLock.writeLock();
private volatile int i=0;
public void reader(){
readLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"读到的值为"+i+System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}finally {
readLock.unlock();
}
}
public void write(int i){
writeLock.lock();
try {
Thread.sleep(2000);
this.i=i;
System.out.println(Thread.currentThread().getName()+"写入的值为"+i+Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
}finally {
writeLock.unlock();
}
}