2013 1113:
这个类实现了接口
ReadWriteLock
{
Lock readLock();
Lock writeLock();
}
两个方法分别返回ReentrantReadWriteLock对象持有的属性readLock和writeLock。
两个Lock属性,具有lock和unlock方法,其实现全部转移到NonfairSync和FairSync中去了,也就是AbstractQueuedSynchronizer的两个子类。
所以说,读写锁,仍然是用AbstractQueuedSynchronizer中的CAS队列来实现的。
读写锁不支持Condition,调用Lock的newCondition方法,将会抛出异常。
所以读写锁的CAS队列中,只有Node.SIGNAL和Node.SHARED两种节点。
读锁成功以后,会将state增加0x10000,所以,有多少把读锁在同时运行,state就有多少个0x10000。
而写锁和ReentrantLock的处理是一样的,没有区别,只有1和0两种情况。
在暂时不能获取到锁的情况下,readLock去lock的时候,会生成一个Node.SHARED类型节点;而writeLock会生成一个Node.SIGNAL类型节点。新生成的节点,会被添加到CAS队列尾部。
写锁unlock以后,会直接唤醒CAS第一个Node。读锁unlock以后,会通过state查看是否全部shared锁都释放完了,只有全部释放完了,才会去唤醒CAS第一个Node。
而一旦读锁得到了执行机会,就会首先将全部shared线程全部唤醒。
一个测试读写锁执行的例子:
package lock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class TestReadWrite {
static ReadWriteLock lock = new ReentrantReadWriteLock();
static Lock readlock = lock.readLock();
static Lock writeLock = lock.writeLock();
public static void main(String[] args) {
Thread a = new Thread(new R(readlock));
Thread b = new Thread(new R(readlock));
Thread c = new Thread(new R(readlock));
Thread d = new Thread(new R(writeLock));
a.start();
b.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
d.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
c.start();
}
static class R implements Runnable {
Lock l;
public R(Lock l) {
this.l = l;
}
@Override
public void run() {
l.lock();
System.out.println("start lock " + l);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end lock " + l);
l.unlock();
}
}
}