1 框架是一个抽象类,但是没有抽象方法
2 需要覆盖一些方法实现自己特定功能的锁,框架会调用这些方法做一些判断,通常返回值是boolean,下面这些都是需要自己实现,很明显它们直接抛异常,等着你实现.
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}
3 final方法不可以覆盖:这些是框架来调用
//acquireQueued让阻塞队列里的节点线程有机会重新获得锁,框架已经实现
//addWaiter(Node.EXCLUSIVE)把当前节点加入到队列中,框架已经实现
//获取锁失败,就把线程变成一个node加入到阻塞队列中,在阻塞队列中用死循环(自旋)完成"尝试获得锁(tryAcquire)--->park(阻塞)--->unpark(被唤醒)-->尝试获得锁-->",这里尝试获得锁必须满足当前线程节点的前一个节点是头节点,头节点代表已经获得锁的节点.因此这是默认的公平锁
//release方法只唤醒head节点的后续一个节点,如果后续一个节点代表的线程被取消,则从后往前选一个没有被取消的节点.所以并不是唤醒所有的节点.
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
4 lock.lock(),condition.await() , lock.unlock()这是condition的用法,类似synchronised和wait的用法
5 public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable.
ReentrantReadWriteLock组合aqs的抽象类syn,syn实现了acquireShared(1), acquire(1).
读锁和写锁实现lock接口,组合syn,两个都是共享一个ReentrantReadWriteLock,共享ReentrantReadWriteLock的syn,
读锁lock调用sync.acquireShared(1);, 写锁调用sync.acquire(1);
公平锁static final class FairSync extends Sync 继承Sync实现其中虚函数
static final class FairSync extends Sync {
private static final long serialVersionUID = -2274990926593161451L;
final boolean writerShouldBlock() {
return hasQueuedPredecessors();
}
final boolean readerShouldBlock() {
return hasQueuedPredecessors();
}
}
非公平锁static final class NonFairSync extends Sync 继承Sync实现其中虚函数
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -8159625535654395037L;
final boolean writerShouldBlock() {
return false; // writers can always barge
}
final boolean readerShouldBlock() {
/* As a heuristic to avoid indefinite writer starvation,
* block if the thread that momentarily appears to be head
* of queue, if one exists, is a waiting writer. This is
* only a probabilistic effect since a new reader will not
* block if there is a waiting writer behind other enabled
* readers that have not yet drained from the queue.
*/
return apparentlyFirstQueuedIsExclusive();
}
}