J.U.C 之 Semaphore 简单应用

2020-06-24  本文已影响0人  吉他手_c156

Semaphore(信号量),是一种计数器,用来保护一个或者多个共享资源的访问,如果线程要访问一个资源就必须先获得信号量,如果信号量内部计数器大于 0 ,信号量减 1,然后允许共享这个资源,否则,如果信号量的计数器等于 0,信号量会把线程置入休眠,直至计数器大于 0,当信号量使用完时,必须释放

构造方法

public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }
    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

主要的方法

Semophore 模拟简单限流场景

public class SemaphoreDemo{

    public static void main(String[] args) {
        // 令牌数最大 5 个,没有令牌无法访问
        Semaphore semaphore = new Semaphore(5);
        // 模拟 50 个线程,每次最多 5 个线程访问
        for (int i = 0; i < 50; i++) {
            new Thread(new Car(semaphore,i)).start();
        }
    }

    static class Car implements Runnable{
        Semaphore semaphore;
        int num;
        public Car(Semaphore semaphore,int num){
            this.semaphore = semaphore;
            this.num = num;
        }
        @Override
        public void run() {
            try {
                semaphore.acquire(); // 获得令牌,如果没有获取到令牌 阻塞
                System.out.println("第"+num+"个线程占用了一个令牌");
                // 模拟访问时间
                Thread.sleep(3000);
                System.out.println("第"+num+"个线程释放了一个令牌");
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                semaphore.release(); // 释放令牌
            }
        }
    }
}

结果

第1个线程占用了一个令牌
第3个线程占用了一个令牌
第5个线程占用了一个令牌
第7个线程占用了一个令牌
第9个线程占用了一个令牌
第3个线程释放了一个令牌
第1个线程释放了一个令牌
第11个线程占用了一个令牌
第13个线程占用了一个令牌
第5个线程释放了一个令牌
第15个线程占用了一个令牌
第9个线程释放了一个令牌
第7个线程释放了一个令牌
第17个线程占用了一个令牌
第19个线程占用了一个令牌
第11个线程释放了一个令牌
......
上一篇 下一篇

猜你喜欢

热点阅读