Semaphore

2022-04-26  本文已影响0人  嘘寒问暖

Semaphore叫做信号量,和前⾯两个不同的是,它的计数器是递增的。

public class SemaphoreTest {

    private static int num =3;

    private static int initNum =0;

    private static Semaphore semaphore =new Semaphore(initNum);

    private static ExecutorService executorService =

Executors.newFixedThreadPool(num);

    public static void main(String[] args) throws Exception {

        executorService.submit(() ->{

            System.out.println("A在上厕所");

            try {

                Thread.sleep(4000);

                semaphore.release();

                System.out.println("A上完了");

            } catch (Exception e) {

                e.printStackTrace();

            } finally {

}

        });

        executorService.submit(() ->{

            System.out.println("B在上厕所");

            try {

                Thread.sleep(2000);

                semaphore.release();

                System.out.println("B上完了");

            } catch (Exception e) {

                e.printStackTrace();

            } finally {

}

        });

        executorService.submit(() ->{

            System.out.println("C在上厕所");

            try {

                Thread.sleep(3000);

                semaphore.release();

                System.out.println("C上完了");

            } catch (Exception e) {

                e.printStackTrace();

            } finally {

}

        });

        System.out.println("等待所有⼈从厕所回来开会...");

        semaphore.acquire(num);

        System.out.println("所有⼈都好了,开始开会...");

        executorService.shutdown();

    }

}

输出结果为:

稍微和前两个有点区别,构造函数传⼊的初始值为0,当⼦线程调⽤release()⽅法时,计数器递增,主线程acquire()传参为3则说明主线程⼀直阻塞,直到计数器为3才会返回。

Semaphore还还还是基于AQS实现的,同时获取信号量有公平和⾮公平两种策略

1. 主线程调⽤acquire()⽅法时,⽤当前信号量值-需要获取的值,如果⼩于0,则进⼊同步阻塞队列,⼤于0则通过CAS设置当前信号量为剩余值,同时返回剩余值

2. ⼦线程调⽤release()给当前信号量值计数器+1(增加的值数量由传参决定),同时不停的尝试因为调⽤acquire()进⼊阻塞的线程

上一篇下一篇

猜你喜欢

热点阅读