一、Semaphore信号量底层原理
1、Semaphore用于限制可以访问某些资源(物理或逻辑的)的线程数目,他维护了一个许可证集合,有多少资源需要限制就维护多少许可证集合,假如这里有N个资源,那就对应于N个许可证,同一时刻也只能有N个线程访问。一个线程获取许可证就调用acquire方法,用完了释放资源就调用release方法
2、可以简单理解为Semaphore信号量可以实现对接口限流,底层是基于aqs实现
二、Semaphore工作原理
1、可以设置Semaphore信号量的状态state值为5
2、当一个线程获取到锁的情况下,将state减1,锁释放成功之后state加1
3、当state<0,表示没锁的资源,则当前线程阻塞
三、Semaphore例子
package webapp;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(5); //最多支持5个访问
for (int i = 0; i < 10; i++) {
int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
//获取票据,aqs锁的状态减1
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "," + finalI);
Thread.sleep(1000);
//aqs锁的状态加1
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
执行结果:
先打印5个线程,暂停1秒,再打印另外5个线程。因为锁没资源了,等5个线程执行完,释放资源后继续执行
四、CountDownLatch底层原理
CountDownLatch是一种java.util.concurrent包下一个同步工具类,它允许一个或多个线程等待直到在其他线程中一组操作执行完成。和join方法非常类似
CountDownLatch底层是基于AQS实现的
CountDownLatch countDownLatch = new CountDownLatch(2); //AQS的state状态为2
调用countDownLatch.countDown();方法的时候,状态减1,当AQS状态state为0的情况下,则唤醒正在等待的线程
五、CountDownLatch例子
package webapp;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(2); //aqs状态为2
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t1开始执行...");
countDownLatch.await(); //线程阻塞
System.out.println("t1结束执行...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1").start();
countDownLatch.countDown(); //aqs状态减1
countDownLatch.countDown();
}
}