可重入原理
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//支持锁重入,只有state减为0,才能释放成功
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
可打断原理
不可打断
private final boolean parkAndCheckInterrupt() {
//打断标记为true,则park会失效
LockSupport.park(this);
//interrupted会清除打断标记
//interrupted返回打断标记,将打断标记设置为true
return Thread.interrupted();
}
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);
}
}
注意:
interrupt的标记为true,会导致park无效可见,只要permit为1或者中断状态为true,那么执行park就不能够阻塞线程。park只可能消耗掉permit,但不会去消耗掉中断状态。
伪代码写一下:
park() {
if(permit > 0) {
permit = 0;
return;
}
if(中断状态 == true) {
return;
}
阻塞当前线程; // 将来会从这里被唤醒
if(permit > 0) {
permit = 0;
}
}
unpark(Thread thread) {
if(permit < 1) {
permit = 1;
if(thread处于阻塞状态)
唤醒线程thread;
}
}
可打断
public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
//如果没有获得锁,进入
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
//在park过程中,如果被intertupt会进入此
//这时候抛出异常,而不会再次进入for(;;)
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
公平锁
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
//与公平锁的主要区别在于 tryAcquire 方法实现
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//先检查AQS 队列中是否由前期节点,没有才去竞争
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;
}
//AQS继承过来的方法
public final boolean hasQueuedPredecessors() {
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
//h!=t,表示队列中有Node
return h != t &&
( //(s=h.next)==null,表示队列中还有没有老二
(s = h.next) == null ||
//或者老二就是不是我
s.thread != Thread.currentThread());
}
再看看继承关系