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