java面试题-Semaphore、CountDownLatch 的实现原理是什么?
引言
在多线程编程中,Semaphore(信号量)和CountDownLatch(倒计时门栓)是两个常用的同步工具,用于协调线程的执行流程。本教程将深入浅析Semaphore和CountDownLatch的实现原理,通过详细的示例代码和解析,帮助初学者深入理解这两个工具的内部机制。
1. Semaphore(信号量)的实现原理
1.1 概念介绍
Semaphore通过new Semaphore(permits)
来创建,其中permits
表示同一时间可以执行多少个线程。通过acquire
来获得许可,通过release
来释放许可。在同一时间只允许permits
个线程同时运行。
1.2 实现原理解析
- 调用
new Semaphore(permits)
时,内部创建了一个NonfairSync
对象,permits
表示信号量的初始值。 - 当调用
acquire()
申请许可时,实际上调用了NonfairSync
的nonfairTryAcquireShared
方法。 - 获取共享锁的过程是调用
nonfairTryAcquireShared
方法,将state
减1,如果state
小于0,则表示许可不足,申请许可失败,当前线程会构造成Waiter
结点放入同步队列中。 - 如果
state
大于等于0,通过CAS(Compare and Swap)去更新state
的值,如果CAS失败,则会一直循环尝试,直到成功。 - 如果CAS设置成功,表示持有锁成功。
- 如果CAS设置锁失败,将当前线程构造成
Waiter
结点放入同步队列中,线程处于等待状态。 - 当调用
release
后或发生线程中断时,等待的线程开始争抢锁。
1.3 示例代码
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private final Semaphore semaphore = new Semaphore(5);
public void executeTask() {
try {
semaphore.acquire(); // 获取许可
// 执行任务的逻辑
// ...
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 释放许可
}
}
}
在上述代码中,通过acquire
获取许可,执行任务的逻辑,然后通过release
释放许可。
2. CountDownLatch的实现原理
2.1 概念介绍
CountDownLatch内部维护了一个计数器,通过countDown
方法将计数器减1,当计数器为0时,所有阻塞的线程从await
方法返回。
2.2 实现原理解析
CountDownLatch的原理主要涉及到计数器的减少和阻塞线程的唤醒。
- 每次调用
countDown
方法会将内部计数器减1。 - 如果计数器为0,唤醒所有阻塞在
await
上的线程。 - 阻塞的线程在
await
时,会检查计数器是否为0,如果不为0,线程将被挂起。 - 如果计数器为0,线程被唤醒,继续执行后续逻辑。
2.3 示例代码
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
private final CountDownLatch latch = new CountDownLatch(3);
public void executeTask() {
// 执行任务的逻辑
// ...
latch.countDown(); // 计数器减1
}
public void awaitCompletion() {
try {
latch.await(); // 阻塞等待计数器为0
// 所有任务完成后的逻辑
// ...
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上述代码中,通过countDown
方法将计数器减1,通过await
方法阻塞等待计数器为0,从而实现线程协作的效果。
3. 总结
本教程深入浅析了Semaphore和CountDownLatch的实现原理,通过分析其内部机制和提供的API,帮助初学者更好地理解和应用这两个同步工具。通过示例代码演示,使读者能够清晰地了解在实际编程中如何使用Semaphore和CountDownLatch。
- 本文标签: Java 面试题
- 本文链接: https://www.jietongc.com/article/98
- 版权声明: 本文由大熊科技原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权