Java——多线程7 可中断锁 可冲入锁 公平锁 非公平锁
可中断式获取锁
public final void acquireInterruptibly(int arg)
throws InterruptedException {
//如果当前线程处于中断状态,抛出一个异常,方法退出
if (Thread.interrupted())
throw new InterruptedException();
//如果不是中断状态并且获取锁失败
if (!tryAcquire(arg))
//
doAcquireInterruptibly(arg);
}
doAcquireInterruptibly
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())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
中断策略:1.一进入方法先判断是否中断;2.线程被阻塞时检测到中断抛出异常
超时等待获取锁(在可中断获取锁上新增超时等待):
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
doAcquireNanos(arg, nanosTimeout)
private boolean doAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (nanosTimeout <= 0L)
return false;
final long deadline = System.nanoTime() + nanosTimeout;
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 true;
}
//再次计算当前的截止时间减去当前时间值
nanosTimeout = deadline - System.nanoTime();
//已经超时退出
if (nanosTimeout <= 0L)
return false;
//将前驱结点置为-1,并且当前有没有超时
if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold)
//如果在这个时间内没有被唤醒,这个线程被取消退出
LockSupport.parkNanos(this, nanosTimeout);
if (Thread.interrupted())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
LOCK——AQS:
1.独占锁的获取lock— acquire
2.独占锁的释放unlock—release
3.响应中断获取锁 lockInterrutibly()— acquireInterruptibly()
4.超时获取锁 tryLock(long time,Time unit)—doAcquireNanos(arg,naosTimeout)