主页 > 创业  > 

解析JUC包底层源码实现

解析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()); else acquire(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); }

标签:

解析JUC包底层源码实现由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“解析JUC包底层源码实现