- Semaphore(信号量)
- [ˈseməfɔ:(r)]:塞么for
- 用于控制对某个公共资源的线程访问量
- acquire():获取许可,这个一个阻塞方法,假如没有获取到许可,线程会一直阻塞在这里直到获取到许可为止
- release():释放占用的资源
- 我们用一个简单的例子看一下
- 场景:有5个人要上厕所,但是只有2个坑位
// 我们定义一个上厕所的线程
// 只有2个坑位,但是现在有5个人要上厕所
public class ThreadShit implements Runnable {
// 2 表示只有两个坑位
// false 表示不用根据等待顺序获取坑位,谁抢到是谁的
private static final Semaphore semaphore = new Semaphore(2,false);
private String name;
public ThreadShit(String name) {
this.name = name;
}
@Override
public void run() {
try {
// 获取许可(查看有没有空的坑位)
// 这个一个阻塞方法,假如没有获取到许可,线程会一直阻塞在这里直到获取到许可为止
semaphore.acquire();
System.out.println(this.name+" 终于挤进了厕所,霸占了坑位,脸上露出了喜悦的笑容!");
Thread.sleep(3000);
System.out.println(this.name+" 拉完屎,轻松走出了厕所!");
// 释放许可(坑位用完了,归还坑位)
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 创建一个线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
try {
// 线程
Runnable r1 = new ThreadShit("小明");
Runnable r2 = new ThreadShit("小李");
Runnable r3 = new ThreadShit("小赵");
Runnable r4 = new ThreadShit("小周");
Runnable r5 = new ThreadShit("小魏");
// 执行任务
executor.execute(r1);
executor.execute(r2);
executor.execute(r3);
executor.execute(r4);
executor.execute(r5);
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
输出:
小李 终于挤进了厕所,霸占了坑位,脸上露出了喜悦的笑容!
小赵 终于挤进了厕所,霸占了坑位,脸上露出了喜悦的笑容!
小赵 拉完屎,轻松走出了厕所!
小李 拉完屎,轻松走出了厕所!
小明 终于挤进了厕所,霸占了坑位,脸上露出了喜悦的笑容!
小魏 终于挤进了厕所,霸占了坑位,脸上露出了喜悦的笑容!
小魏 拉完屎,轻松走出了厕所!
小周 终于挤进了厕所,霸占了坑位,脸上露出了喜悦的笑容!
小明 拉完屎,轻松走出了厕所!
小周 拉完屎,轻松走出了厕所!
从上面输出可以看出,当前只有2个坑位,但是有5个人同时要上厕所,那只能等待,当有人出来时才能有人进去