个人学习笔记
介绍:支持重入性,能够对共享资源重复加锁,即获取锁的线程能够再次获取锁,而不被阻塞
需要学习两点内容:
1、重入性实现原理
在线程获取锁的时候,如果当前线程已经获取锁了,再次获取成功;由于锁被获取n次,需要释放n次,才算完全释放锁
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//1. 如果该锁未被任何线程占有,该锁能被当前线程获取
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//2.若被占有,检查占有线程是否是当前线程
else if (current == getExclusiveOwnerThread()) {
// 3. 再次获取,计数加一
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
2、公平锁与非公平锁
所谓公平,即锁的获取顺序应该符合请求上的绝对时间顺序,满足FIFO。
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;
}
}
与nonfairTryAcquire唯一不同的点是: hasQueuedPredecessors(),判断当前节点是否有前驱节点,如果有,当前线程请求锁失败。
总结:公平锁每次都是从同步队列中第一个节点获取锁,而非公平锁则不一定,有可能刚释放锁的线程能再次获取到锁。