之前的acquire函数会先调用tryAcquire去尝试获得锁,这个在每个具体类中实现,这里看ReentrantLock中2个实现。
公平锁FairSync中:
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//状态为0表示可以加锁
if (!hasQueuedPredecessors() && //hasQueuedPredecessors表示之前的线程是否有在排队的,这里加了!表示没有排队
compareAndSetState(0, acquires)) { //那么就去尝试cas state
setExclusiveOwnerThread(current); //如果cas成功设置排他线程为当前线程,表示成功得到锁
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//如果当前的排他线程是当前线程,表示是重入
int nextc = c + acquires; //重入计数器增加
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);//因为已经获得锁了,所以不用cas去设,直接设值就行
return true;
}
return false;
}
非公平锁中:
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//不同于公平锁中,没有hasQueuedPredecessors这个函数,表示当非公平锁去加锁的时候,不会去看有没有线程在排队,直接去抢锁,如果抢到了后续一样。否则会去排队(后续代码再看)
//之前课程上讲过”一朝排队永远排队“就是这个意思,排队中的非公平并不会去抢先
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;
}
网友评论