欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 解析JUC包底层源码实现

解析JUC包底层源码实现

2025/2/22 2:17:47 来源:https://blog.csdn.net/sosovo66/article/details/145716713  浏览:    关键词:解析JUC包底层源码实现

引言

上篇文章详细讲解了AQS底层架构,由等待队列和同步队列以及state信号量来实现,本篇文章将详细讲解JUC包是如何利用这些架构来实现各种组件的

ReentrantLock(可重入锁)

ReentrantLock 是一个独占锁,同一时刻只允许一个线程获取锁。它通过 AQS 的 state 变量来表示锁的重入次数,state 为 0 表示锁未被持有,大于 0 表示锁已被持有,且值表示持有线程的重入次数。

实现细节:

获取锁:ReentrantLock 有公平锁和非公平锁两种实现,它们都继承自 AQS 并重写了 tryAcquire 方法。以非公平锁为例,当线程尝试获取锁时,会先检查 state 是否为 0,如果是则尝试使用 CAS 操作将 state 设为 1,表示获取锁成功;如果 state 不为 0 且当前线程就是持有锁的线程,则将 state 加 1,表示重入。

static final class NonfairSync extends Sync {final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}
}

释放锁:重写 tryRelease 方法,每次释放锁时将 state 减 1,当 state 减为 0 时,表示锁完全释放,此时会唤醒等待队列中的后继节点。

protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;
}

CountDownLatch(倒计时锁存器)

CountDownLatch 用于让一个或多个线程等待其他线程完成操作。它通过 AQS 的 state 变量作为计数器,初始值为需要等待的操作数量,每当一个操作完成时,调用 countDown() 方法将 state 减 1,当 state 减为 0 时,等待的线程会被唤醒。

实现细节:

初始化:在构造函数中设置 state 的初始值。

public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync = new Sync(count);
}private static final class Sync extends AbstractQueuedSynchronizer {Sync(int count) {setState(count);}
}

等待操作完成:调用 await() 方法,线程会尝试获取共享锁,只有当 state 为 0 时才能获取成功,否则线程会进入等待队列。

public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);
}

操作完成通知:调用 countDown() 方法,会将 state 减 1,当 state 减为 0 时,会唤醒等待队列中的所有线程。

public void countDown() {sync.releaseShared(1);
}

Semaphore(信号量)

Semaphore 用于控制同时访问某个资源的线程数量。它通过 AQS 的 state 变量表示可用的许可数量,线程在访问资源前需要先获取许可(acquire()),访问完成后释放许可(release())。

实现细节:

获取许可:调用 acquire() 方法,线程会尝试获取共享锁,通过减少 state 的值来表示获取许可。如果 state 小于请求的许可数量,则线程会进入等待队列。

public void acquire() throws InterruptedException {sync.acquireSharedInterruptibly(1);
}

释放许可:调用 release() 方法,会增加 state 的值,表示释放许可,同时会唤醒等待队列中的线程。

public void release() {sync.releaseShared(1);
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词