锁(三):ReentrantLock源码之公平锁的实现
- 公平锁与非公平锁的区别
公平锁:所有线程都老老实实排队
非公平锁:只要有机会,就先尝试抢占资源
- 非公平锁的弊端
可能导致后面排队等待的线程等不到相应的cpu资源,从而引起线程饥饿
- 源码解析
public class ReentrantLockDemo {
public static void main(String[] args) {
// 传入参数true,表示获得公平锁的实现
ReentrantLock reentrantLock = new ReentrantLock(true);
reentrantLock.lock();
reentrantLock.unlock();
}
}
- ctrl查看源码
public void lock() {
sync.acquire(1);
}
- 查看acquire方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
- 查看tryAcquire方法
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
- 查看tryAcquire方法的实现
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
@ReservedStackAccess
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;
}
}
- 查看hasQueuedPredecessors方法
public final boolean hasQueuedPredecessors() {
Node h, s;
if ((h = head) != null) {
if ((s = h.next) == null || s.waitStatus > 0) {
s = null; // traverse in case of concurrent cancellation
for (Node p = tail; p != h && p != null; p = p.prev) {
if (p.waitStatus <= 0)
s = p;
}
}
if (s != null && s.thread != Thread.currentThread())
return true;
}
return false;
}
-
ctrl + shift + y翻译
-
继续查看tryAcquire方法的实现
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
@ReservedStackAccess
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread(); // 获取当前线程
int c = getState(); // 获取状态
if (c == 0) {
if (!hasQueuedPredecessors() && // 如果状态为0 ,且如果没有其他线程在等待,就尝试获取锁
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current); // 将当前线程设置成持有锁的线程
return true;
}
}
else if (current == getExclusiveOwnerThread()) { // 如果状态>0,即当前线程是持有锁的贤臣
int nextc = c + acquires; // 状态加1
if (nextc < 0) // 越界时报错
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}