当前位置: 首页 > 后端技术 > Java

[java并发编程]基于信号量限流器的实现

时间:2023-04-01 13:59:07 Java

[TOC]1.什么是信号量“semaphore”在编程术语中,都会用到信号量这个词,那么什么是“信号量”呢?信号灯就像在厨房入口处的架子上放了三个锅。如果你的孩子拿走了一把热牛奶,你的妻子拿走了一把热汤,你的妈妈拿走了一把做饭,你想煮面就没有锅了。当你看到这个时,你不会进入厨房,你处于等待状态。也就是说,厨房以“锅数”作为信号量,只能容纳三个人(线程)。老婆烧完汤,把锅放回架子上,你去拿锅,进厨房。2.信号量类Semaphore通过上面的介绍,我们可以总结出信号量计数器的重要部分:计算信号量的使用量,pot(信号)使用一次减1,pot(信号)返回一次并相加1等待队列:当任务数大于信号量上限时,任务进入等待队列。信号量由JDK中的java.util.concurrent.Semaphore实现,Semaphore提供了两个构造函数。permits参数表示信号量的个数(盆数),fair表示信号量的获取是否遵循公平原则。所谓公平原则就是:先启动的线程调用semaphore.acquire();methodfirst,然后先得到信号“permit”,遵循先到先得的原则。publicSemaphore(intpermits)publicSemaphore(intpermits,booleanfair)公共方法列表方法名函数acquire()获取许可,在获取许可之前,线程处于阻塞状态tryAcquire()尝试获取许可,并且获取成功返回true,否则返回false,不阻塞线程。tryAcquire(longtimeout,TimeUnitunit)和tryAcquire()的大部分实现一样,不同的是提供了超时设置,在超时范围内多次尝试不会阻塞线程。availablePermits()获取剩余信号许可数release()释放一个许可并唤醒一个等待信号许可的线程hasQueuedThreads()返回一个boolean类型,判断等待队列中是否还有等待线程线程数3.实现限流器通过上面的介绍,相信大家肯定能想到Semaphore的应用场景。例如:医院门诊编号机,三个值班医生是三个信号量许可,当超过信号量时,如果要看病,只能在停车场等待停车功能,n个车位是n个信号量许可,当信号量的数量超过数量的时候,想要停车只能等,应用场景有很多很多。让我们自己找出创意。其实无论有多少应用场景,说白了:Semaphore实现的就是一个限流器。下面以我们厨房的三锅为例,实现基于信号量的限流。publicclassTestKitchenSemaphore{//Semaphore-3potsprivatestaticSemaphorethreeWoks=newSemaphore(3);publicstaticvoidmain(String[]args)throwsInterruptedException{//模拟5人抢3盆的场景for(inti=0;i<5;i++){Thread.sleep(1000);//模拟进厨房的顺序,有一个时间间隔newThread(()->{try{threeWoks.acquire();//获得一个许可,信号量计数器减1System.out.println(Thread.currentThread().getName()+"拿一壶,还有"+threeWoks.availablePermits()+"拿一壶");Thread.sleep(newRandom().nextInt(5000));//模拟锅的使用时长threeWoks.release();//释放许可,信号量计数器加1System.out.println(Thread.currentThread().getName()+"退一锅,还剩"+threeWoks.availablePermits()+"拿锅");}catch(InterruptedExceptione){e.printStackTrace();}}).start();}}}上面代码的输出结果如下,我们可以看到信号量每acquire减1,信号量每release加1。信号量上限为3,下限为0。当达到上限时,只有先占用potpermit的线程被释放后,其他线程才能获得potpermit。Thread-0拿了一锅还剩2锅Thread-1拿了一锅还剩1锅Thread-2拿了一锅还剩0锅=>备注:5一个线程只能拿3锅(上限)。Thread-1返回一锅,还剩一锅。Thread-3拿一锅,还剩0锅=>备注:只有返回才能返回被占用,不超过3Thread-0返回一锅,还剩1锅Thread-4拿一锅,0锅left=>备注:只有返回才能被再次占用,不能超过3个Thread-2返回一锅,还剩一锅Thread-3返回一锅,还剩两锅Thread-4返回一锅,还剩三锅=>备注:使用后依次发布,欢迎关注我如果觉得对您有帮助,请点赞分享!您的支持是我创作不竭的动力!.另外,作者近期输出了以下优质内容,期待大家的关注。《kafka修炼之道》《手摸手教你学Spring Boot2.0》《Spring Security-JWT-OAuth2一本通》《实战前后端分离RBAC权限管理系统》《实战SpringCloud微服务从青铜到王者》

猜你喜欢