【Java】--Semaphore的介绍及应用

    技术2022-07-10  130

    Semaphore

    简介

    Semaphore是java.util.concurrent包下的同步工具,它通过维护若干个许可证来控制线程对共享资源的访问。

    Semaphore翻译成字面意思为 信号量, Semaphore所维护的许可证数量就是允许访问共享资源的最大线程数量,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

    方法说明

    构造器

    // 参数permits表示许可数目,即同时可以允许多少线程进行访问 public Semaphore(int permits) { sync = new NonfairSync(permits); } // 这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可 public Semaphore(int permits, boolean fair) { sync = (fair)? new FairSync(permits) : new NonfairSync(permits); }

    acquire

    获取许可,若无许可能够获得,则会一直等待,直到获得许可。

    public void acquire() throws InterruptedException { } //获取一个许可 public void acquire(int permits) throws InterruptedException { } //获取permits个许可

    release

    释放许可

    public void release() { } //释放一个许可 public void release(int permits) { } //释放permits个许可

    注意 在释放许可之前,必须先获获得许可。

    应用案例

    吃海底捞

    大家都喜欢吃海底捞,但是海底捞的座位有限的,不可能所有人都同时就餐。

    将海底捞的座位看做有限的资源,大家都去争抢座位时,必然会有人争抢成功顺利就餐,有人争抢失败在门口等候。

    public class SemaphoreDemo { public static void main(String[] args) { int num = 3; Semaphore semaphore = new Semaphore(num);// 3个座位 for (int i = 0; i < 6; i++) { new Thread(() -> { try { semaphore.acquire(); System.out.println(Thread.currentThread().getName() + "\t 抢到座位,开始就餐"); // 吃饭时间1秒 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "\t 吃完离开"); } catch (InterruptedException e) { e.printStackTrace(); }finally { semaphore.release();// 释放资源 } },String.valueOf(i) ).start(); } } }

    运行结果:

    0 抢到座位,开始就餐 2 抢到座位,开始就餐 3 抢到座位,开始就餐 2 吃完离开 0 吃完离开 4 抢到座位,开始就餐 3 吃完离开 1 抢到座位,开始就餐 5 抢到座位,开始就餐 4 吃完离开 5 吃完离开 1 吃完离开 Process finished with exit code 0
    Processed: 0.018, SQL: 9