java高并发、多线程(六)
ReentrantLock
ReentrantLock源码结构:
public class ReentrantLock implements Lock, java.io.Serializable {
private final Sync sync;
//锁实现类
abstract static class Sync extends AbstractQueuedSynchronizer {/*...*/}
//非公平锁实现
static final class NonfairSync extends Sync {/*...*/}
//公平锁实现
static final class FairSync extends Sync {/*...*/}
//默认为非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
//参数为true为公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
}
从上面的结构可以知道,ReentrantLock 类内部包含Sync 、NonfairSync 、FairSync 3个内部类,其中NonfairSync 、FairSync均继承自Sync ,二则差异主要是各自实现的公平与非公平锁。
NonfairSync类
static final class NonfairSync extends Sync {
//加锁
final void lock() {}
//尝试以独占模式获取锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
从上面源码可以知道,NonfairSync主要实现了lock()以及tryAcquire(int)方法。
tryAcquire(int)
上一节我们介绍AQS的时候说到子类根据各自需求需要实现几个方法,这里NonfairSync 实现tryAcquire(尝试以独占模式获取锁)方法,因此NonfairSync 是使用的独占锁的模式:
//尝试以独占模式获取锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
从代码中可以看出tryAcquire调用的父类Sync的nonfairTryAcquire方法。我们再继续看一下nonfairTryAcquire的实现:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
//获取当前线程的同步状态state
int c = getState();
//为0时表示当前线程未获取到锁
if (c == 0) {
//利用CAS进行加锁
if (compareAndSetState(0, acquires)) {
//加锁成成功则设置线程拥有独占访问
setExclusiveOwnerThread(current);
return true;
}
}
//判断当前线程是否拥有独占访问
else if (current == getExclusiveOwnerThread()) {
//累加参数acquires
int nextc = c + acquires;
//溢出,如果并发量特别大需要注意
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//设置state
setState(nextc);
return true;
}
return false;
}
lock()
final void lock() {
//CAS加锁
if (compareAndSetState(0, 1))
//成功,则设置线程拥有独占访问
setExclusiveOwnerThread(Thread.currentThread());
else
//调用父类AQS具体实现
acquire(1);
}
接着我们继续查看AQS中acquire(int)方法:
public final void acquire(int arg) {
//尝试以独占模式获取锁
if (!tryAcquire(arg) &&
//获取不到则加入到等待队列中获取
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
//中断当前线程
selfInterrupt();
}
继续查看addWaiter():
private Node addWaiter(Node mode) {
//创建node
Node node = new Node(Thread.currentThread(), mode);
// 获取尾指针node
Node pred = tail;
if (pred != null) {
//将创建的node的前驱节点设置为原尾节点
node.prev = pred;
//同步设置当前节点为尾节点
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//入队
enq(node);
return node;
}
继续查看acquireQueued():
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
//获取前驱节点
final Node p = node.predecessor();
//前驱节点为头节点,尝试获取独占锁
if (p == head && tryAcquire(arg)) {
//设置头节点为当前节点
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//检查更新等待状态
if (shouldParkAfterFailedAcquire(p, node) &&
//中断线程
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
//取消获取锁操作
cancelAcquire(node);
}
}
继续查看shouldParkAfterFailedAcquire():
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
//获取等待状态
int ws = pred.waitStatus;
//如果状态为SIGNAL,正常等待
if (ws == Node.SIGNAL)
return true;
//大于0即CANCELLED状态
if (ws > 0) {
//跳过取消的节点
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
//修改等待状态为SIGNAL
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
继续查看parkAndCheckInterrupt():
private final boolean parkAndCheckInterrupt() {
//利用LockSupport的park方法进行阻塞
LockSupport.park(this);
//返回阻塞状态
return Thread.interrupted();
}
FairSync 类
下面我们来看看公平锁的具体实现:
static final class FairSync extends Sync {
final void lock() {
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//查看队列是否还有未执行的任务
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
继续查看hasQueuedPredecessors()的具体实现:
public final boolean hasQueuedPredecessors() {
Node t = tail;
Node h = head;
Node s;
//是否为空队列或者当前线程是否为队列的头
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
Sync类
关于Sync类,我们这里就简单的看一下他的tryRelease(int)以及isHeldExclusively()方法的具体实现:
protected final boolean tryRelease(int releases) {
// 减去同步状态值
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//未获取到锁
if (c == 0) {
free = true;
//设置独占为null
setExclusiveOwnerThread(null);
}
//修改同步状态
setState(c);
return free;
}
protected final boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}