XiaoBai_DaShen的博客通过本文主要向大家介绍了源码,java,锁等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
本篇重点介绍一下 ReentrantLock 的其他几个重要的方法:
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
void lockInterruptibly()
在上一篇的时候已经讲过,它是一个响应中断的获取锁的方法,线程在获取同步状态的过程中如果被中断,直接抛出异常。
二、尝试获取同步状态
对于 boolean tryLock()
方法,看一下源码:
public boolean tryLock() {
return sync.nonfairTryAcquire(1);
}
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;
}
第二个方法是 AbstractQueuedSynchronizer
类中的方法。如果同步状态没有被其他线程获取,则当前线程直接获取,并返回 true,否则获取同步状态失败,返回 false。也就是说这是一个非阻塞的获取锁的方式,不能获取锁时,并不进入同步队列中,而是直接返回。比较简单。
三、超时获取同步状态
老样子,看源码:
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
//响应中断的
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
//先获取同步状态,成功直接返回,
//失败的话执行 doAcquireNanos(arg, nanosTimeout)
return tryAcquire(arg) ||
doAcquireNanos(arg, nanosTimeout);
}
private boolean doAcquireNanos(int arg, long nanosTimeout)
throws InterruptedException {
//等待时间小于等于0的话,直接返回false,获取失败。
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();
//如果剩余时间没了,返回false,获取失败。
if (nanosTimeout <= 0L)
return false;
//如果还剩下时间的话,检查是否可以进入waiting状态
// 并检查剩余时间知否大于spinForTimeoutThreshold
if (shouldParkAfterFailedAcquire(p, node) &&
nanosTimeout > spinForTimeoutThreshold)
//park线程,线程等待时长为剩余时间大小
LockSupport.parkNanos(this, nanosTimeout);
if (Thread.interrupted()) //响应中断
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
分析都在代码中,也是比较简单的。
这一篇比较简单哈。ReentrantLock 就写到这吧,当然,还有一个构件 Condition,以后有机会再写。