笔试被问了一个pthread+mutex实现读写锁,回来一看原来跟java 里的Thread,lock , condition是完全一致的概念,faint。
当然,知道也没用,像我这总弱鸡也就用用读写锁,连人家代码都没看过。
参考
http://yhjhappy234.blog.163.com/blog/static/3163283220135178183769/
http://developer.51cto.com/art/201103/249288.htm
简要介绍
读写锁是concurrent包里比较使用广泛的锁了,实现逻辑是读可重入,写操作无法重入且与读操作互斥。当然,还有很多其他调度特性,降级特性,我觉得我们可以先从基本实现来看
分析1-用例
学东西先从例子看起吧,先看个JDK官方给的例子:使用ReentrantReadWriteLock做cache的例子,不过感觉讲的是读写锁之间怎么转换。
class CachedData {
Object data;
volatile boolean cacheValid;
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
}
分析2-基本实现
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable
public static class ReadLock implements Lock, java.io.Serializable
public static class WriteLock implements Lock, java.io.Serializable
/** Inner class providing readlock */
private final ReentrantReadWriteLock.ReadLock readerLock;
/** Inner class providing writelock */
private final ReentrantReadWriteLock.WriteLock writerLock;
/** Performs all synchronization mechanics */
private final Sync sync;
public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
在ReentrantReadWriteLock内部实现了ReadLock和WriteLock两个类,但仔细看这两个类的实现发现他们全部由一个Sync来具体实现的
public ReentrantReadWriteLock() {
this(false);
}
public ReentrantReadWriteLock(boolean fair) {
sync = (fair)? new FairSync() : new NonfairSync();
readerLock = new ReadLock(this);
writerLock = new WriteLock(this);
}
这是两个lock的lock方法
public void lock() {//write Lock
sync.acquire(1);
}
public void lock() {//read Lock
sync.acquireShared(1);
}
所以我们具体看一下Sync的实现吧,
abstract static class Sync extends AbstractQueuedSynchronizer
Sync是AQS的子类,