https://www.cnblogs.com/gustavo

Gustavo's Blog

人类的赞歌是勇气的赞歌!

Semaphore

🐱‍🐉 介绍

Semaphore 信号量,用来控制同一时间<span m+="" 2m="" regular";color:#0c0c0c;background:="" #ffc000"="">,资源可被<span microsoft="" yahei";color:#0c0c0c;background:="" #ffc000"="">访问的线<span m+="" 2m="" regular";color:#0c0c0c;background:="" #ffc000"="">程数量,一般可用于流量的控制。

底层依赖 AQS 的状态 State

其内部是基于AQS的共享模式,AQS的状态表示许可证的数量,在许可证数量不够时,线程将会被挂起;

而一旦有一个线程释放一个资源,那么就有可能重新唤醒等待队列中的线程继续执行。

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

🤷‍♂️ 使用场景

 

资源有明确数量限制的场景,限流,熔断,降级等。

◾ 数据库连接池,连接不能超过限制数量,当连接达到了限制数量后,后面的线程只能排队等前面的线程释放了数据库连接才能获得数据库连接。

◾ 某些排队场景,能够容纳同时在线人数有限,超过后只能排队等待。

◾资源访问,服务限流(Hystrix 里限流就有基于信号量方式),可以使用 tryAcquire(long timeout, TimeUnit unit) 方法,在超时做其他处理(降级、熔断等)。

 

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

🍖 方法及使用

 

🔸 构造方法

 

◾ 创建给定许可数量的非公平的 Semaphore

public Semaphore(int permits) {

    sync = new NonfairSync(permits);

}

 

◾ 创建给定许可数量的非公平的或公平的 Semaphore

public Semaphore(int permits, boolean fair) {

    sync = fair ? new FairSync(permits) : new NonfairSync(permits);

}

 

 

🔸 方法说明

 

 

🔸 使用示例

 

 

public class SemaphoreTest {

    static class Parking {

        //信号量

        private Semaphore semaphore;

 

        Parking(int count) {

            semaphore = new Semaphore(count);

        }

 

        public void park() {

            try {

                //获取信号量

                semaphore.acquire();

                long time = (long) (Math.random() * 10000);

                System.out.println(Thread.currentThread().getName() + "进入停车场,停车" + time + "秒...");

                Thread.sleep(time);

                System.out.println(Thread.currentThread().getName() + "开出停车场...");

            } catch (InterruptedException e) {

                e.printStackTrace();

            } finally {

                semaphore.release();

            }

        }

    }

 

    static class Car extends Thread {

        Parking parking;

 

        Car(Parking parking) {

            this.parking = parking;

        }

 

        @Override

        public void run() {

            parking.park();     //进入停车场

        }

    }

 

    public static void main(String[] args) {

        Parking parking = new Parking(3);

        for (int i = 0; i < 5; i++) {

            new Car(parking).start();

        }

    }

}

Thread-0进入停车场,停车8243秒...

Thread-2进入停车场,停车7086秒...

Thread-4进入停车场,停车696秒...

Thread-4开出停车场...

Thread-3进入停车场,停车1007秒...

Thread-3开出停车场...

Thread-1进入停车场,停车1972秒...

Thread-1开出停车场...

Thread-2开出停车场...

Thread-0开出停车场...

posted @ 2022-08-20 16:20  BitBean  阅读(49)  评论(0编辑  收藏  举报