- 信号量===>信号灯
- 灯塔、信号灯===>里面有几盏(允许几个参考这个信号灯)
- s.acquire()是阻塞方法,获取不到信号量的时候就会阻塞在那
- 结束之后,要调用s.release()释放一下这个信号量===>让别的线程去获取
- Semaphore的作用—->限流;最多允许多少个线程同时运行(同时买票的人只能有五个)
- acquire是获得许可—->资源,不是获得线程
- 与线程池中Fix那个不一样,那个说明线程池中只能有固定个线程,其他的都是任务,在队列中等待;而Semaphore说明有好多个线程,但是能够同时运行的线程只能有几个
- 这里的Semaphore主要是为了线程同步;而线程池是表示可以有多少个线程
- (车道和收费站、买票的例子)八条车道,两个收费站,好多车谁得到了信号量,谁就先过收费站;但好多车直接扔到线程池中,是没问题的,是都可以执行的,只要没有超过容量(否则需要排队)
- 信号量有同步的概念,而线程池没有同步的概念
- 公平与非公平,默认是非公平的,第二个参数为true时为公平的
- 公平是必须排队(内部有队列),而非公平可以去抢(超车,加塞)
- 上述几个类都是用同一个类来实现的(那个类中有队列)—->AQS(原理),这里面维护了一个先进先出的队列(CLH队列—->高并发最核心的内容)
package com.mashibing.juc.c_020;
import java.util.concurrent.Semaphore;
public class T11_TestSemaphore {
public static void main(String[] args) {
//Semaphore s = new Semaphore(2);
Semaphore s = new Semaphore(2, true);
//允许一个线程同时执行
//Semaphore s = new Semaphore(1);
new Thread(()->{
try {
s.acquire();
System.out.println("T1 running...");
Thread.sleep(200);
System.out.println("T1 running...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
s.release();
}
}).start();
new Thread(()->{
try {
s.acquire();
System.out.println("T2 running...");
Thread.sleep(200);
System.out.println("T2 running...");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}