展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

锁(三):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;
}
}
posted @   DogLeftover  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示