说明
Semaphore 是 java.util.concurrent 包下的一个类
信号量是对锁的扩展,锁一次只允许一个线程访问资源,而信号量却可以 指定多个线程,同时访问某一个资源。
作用
用于多个共享资源的互斥使用
用于并发线程数量的控制
理解
- 饭馆有
5张饭桌 (多个共享资源) - 一个饭桌只能坐
1人 (互斥使用的) - 来了
8个人 - 同时有
5人吃饭 (并发线程数量的控制) - 其他
3个需要等待 - 当有人吃完离开后,才能进去一个吃饭
应用场景
项目中需要使用第三方提供的接口,如:发短信、校验身份证、人脸识别等
第三方供对接口有并发量限制,如:同时发短信,最大并发量不超过50,并发量超过50个不处理(相当于有50张饭桌,可以有成千上万人吃饭,但最多同时吃饭只有50桌)
此时可以使用 Semaphore 信号量
使用
acquire():从信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
相当于获得一个饭桌(前提有空闲饭桌)release():释放一个许可,将其返回给信号量。
相当于吃完离开,饭桌空闲,可以给其他人使用
例子
自定义线程类
package 信号量;
import java.util.concurrent.Semaphore;
public class MyRun3 implements Runnable{
/**
* 信号量,最多同时有5人吃饭
*/
Semaphore sem = new Semaphore(5);
@Override
public void run(){
try {
//获取信号量
sem.acquire();
String name = Thread.currentThread().getName();
System.out.println(name + " 有人占用开始吃饭");
Thread.sleep(3000);
//释放信号量
sem.release();
System.out.println(name + " 吃完离开");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
启动类
package 信号量;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main3 {
public static void main(String[] args) {
MyRun3 myRun = new MyRun3();
// 创建线程池,8个线程,相当于有 8个人
ExecutorService executorService = Executors.newFixedThreadPool(8);
for (int i = 0;i<8;i++){
executorService.execute(myRun);
}
executorService.shutdown();
}
}
执行结果:
参考:
https://www.cnblogs.com/songlove/p/15333552.html
https://baijiahao.baidu.com/s?id=1663727968804364989&wfr=spider&for=pc
