欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于Semaphore的使用介绍

程序员文章站 2022-06-04 22:00:07
...

关于Semaphore的使用介绍

1.什么是Semaphore

Semaphore是一个计数信号量,通常用于限制对某些资源访问的线程数量,Semaphore管理一系列许可证。举个栗子:

  • 假如我们要去游泳池游泳,泳池一共有6条泳道,每条泳道只能有1个人在上面使用。每个人去游泳之前要先 acquire() 一下获取许可证,如果有空闲泳道就可以去游泳;如果没有空闲泳道,就只能阻塞等待。游完泳之后,再 release() 一下释放许可证,释放出该泳道的使用权,确保下一个人 acquire() 的时候可以获取可用泳道,继续游泳。如果泳道上都有人了,再有人过来游泳,就需要等待其他人。
  • 这个泳道的数量,我们是可以自行设定的。这里的泳池就是共享资源,而泳道的数量就是可访问的线程数量,游泳者就是线程。

2.Semaphore的简单使用

public class SemaphoreTest {

    public static void main(String[] args) {
        //创建一个可缓存的线程池
        ExecutorService executor = Executors.newCachedThreadPool();
        //信号量
        Semaphore semaphore = new Semaphore(6);
        System.out.println("初始化: 当前有" + semaphore.availablePermits() + "个泳道可用");
        //创建10个任务(相当于10个游泳者)
        for (int i = 0; i < 10; i++) {
            //记录第几个任务(相当于第几个游泳者)
            final int No = i;
            executor.execute(() -> {
                try {
                    semaphore.acquire();    //获取许可
                    System.out.println(Thread.currentThread().getName() + "游泳者" + No + "获取了许可(获取了泳道)," + "还剩"
                            + semaphore.availablePermits() + "个泳道可用~");
                    //执行耗时操作(相当于正在游泳)
                    Thread.sleep(1000);
                    semaphore.release();    //释放许可
                    System.out.println(Thread.currentThread().getName() + "游泳者" + No + "释放了许可(离开了泳道)," + "还剩"
                            + semaphore.availablePermits() + "个泳道可用~");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        //关闭线程池
        executor.shutdown();
    }
}

打印结果之一,每次运行都可能不一样:

初始化: 当前有6个泳道可用
pool-1-thread-1游泳者0获取了许可(获取了泳道),还剩5个泳道可用~
pool-1-thread-2游泳者1获取了许可(获取了泳道),还剩4个泳道可用~
pool-1-thread-3游泳者2获取了许可(获取了泳道),还剩3个泳道可用~
pool-1-thread-4游泳者3获取了许可(获取了泳道),还剩2个泳道可用~
pool-1-thread-5游泳者4获取了许可(获取了泳道),还剩1个泳道可用~
pool-1-thread-6游泳者5获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-7游泳者6获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-1游泳者0释放了许可(离开了泳道),还剩0个泳道可用~
pool-1-thread-8游泳者7获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-5游泳者4释放了许可(离开了泳道),还剩0个泳道可用~
pool-1-thread-9游泳者8获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-4游泳者3释放了许可(离开了泳道),还剩0个泳道可用~
pool-1-thread-3游泳者2释放了许可(离开了泳道),还剩1个泳道可用~
pool-1-thread-2游泳者1释放了许可(离开了泳道),还剩1个泳道可用~
pool-1-thread-10游泳者9获取了许可(获取了泳道),还剩0个泳道可用~
pool-1-thread-6游泳者5释放了许可(离开了泳道),还剩2个泳道可用~
pool-1-thread-7游泳者6释放了许可(离开了泳道),还剩3个泳道可用~
pool-1-thread-10游泳者9释放了许可(离开了泳道),还剩4个泳道可用~
pool-1-thread-9游泳者8释放了许可(离开了泳道),还剩5个泳道可用~
pool-1-thread-8游泳者7释放了许可(离开了泳道),还剩6个泳道可用~

看了上面的结果,你是不是觉得获取泳道使用权或者释放泳道使用权之后,剩下可用泳道的数量是不是不对呀!其实是没错的,只是因为线程运行太快,acquire()方法或者release()方法在打印语句执行之前,就已经执行了,所以看起来结果才好像不大对。

简单介绍就到这里啦,更多介绍请点击下面链接~

戳我详细了解Semaphore

相关标签: samephore 信号量