会员登录 - 用户注册 - 设为首页 - 加入收藏 - 网站地图 Java高并发编程基础三大利器之Semaphore!

Java高并发编程基础三大利器之Semaphore

时间:2025-11-04 23:30:17 来源:益强数据堂 作者:人工智能 阅读:814次

引言

最近可以进行个税申报了,高并还没有申报的发编同学可以赶紧去试试哦。不过我反正是程基础从上午到下午(3月1日)一直都没有成功的进行申报,一进行申报 就返回“当前访问人数过多,利器请稍后再试”。高并为什么有些人就能够申报成功,发编有些人就直接返回失败。程基础这很明显申报处理资源是利器有限的, 只能等别人处理完了在来处理你的高并,你如果运气好可能重试几次就轮到你了,发编如果运气不好可能重试一天也可能轮不到你。程基础我反正已经是利器放弃了,等到夜深人静的高并时候再来试试。作为一个程序员我们肯定知道这是发编个税申请app的限流操作,如果还有不懂什么 是程基础限流操作的可以参考下这个文章《高并发系统三大利器之限流》。比如个税申报系统每台机器只最多分别最多只能处理1000个请求,再多的请求就会把机器打挂。如果是多余的请求就把这些请求拒绝掉。直接给你返回一句温馨提示:“当前访问人数过多,高防服务器请稍后再试”,如果要实现这个功能大家想想可以通过哪些方法算法来实现。

共享锁、独占锁

学习semaphore之前我们必须要先了解下什么是共享锁。

共享锁:它是允许多个线程同时获取锁,并发的访问共享资源

独占锁:也有人把它叫做“独享锁”,它是是独占的,排他的,只能被一个线程可持有, 当独占锁已经被某个线程持有时,其他线程只能等待它被释放后,才能去争锁,并且同一时刻只有一个线程能争锁成功。

什么是Semaphore

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。很多年以来,我都觉得从字面上很难理解Semaphore所表达的含义,只能把它比作是控制流量的红绿灯,比如XX马路要限制流量,免费信息发布网只允许同时有一百辆车在这条路上行使,其他的都必须在路口等待,所以前一百辆车会看到绿灯,可以开进这条马路,后面的车会看到红灯,不能驶入XX马路,但是如果前一百辆中有五辆车已经离开了XX马路,那么后面就允许有5辆车驶入马路,这个例子里说的车就是线程,驶入马路就表示线程在执行,离开马路就表示线程执行完成,看见红灯就表示线程被阻塞,不能执行。”

Semaphore机制是提供给线程抢占式获取许可,所以他可以实现公平或者非公平,类似于ReentrantLock。说了这么多我们来个实际的例子看一看,比如我们去停车场停车,停车场总共只有5个车位,但是现在有8辆汽车来停车,剩下的3辆汽车要么等其他汽车开走后进行停车,或者去找别的停车位? /**  * @author: 公众号【Java金融】  */ public class SemaphoreTest {     public static void main(String[] args) throws InterruptedException {          // 初始化五个车位         Semaphore semaphore = new Semaphore(5);         // 等所有车子         final CountDownLatch latch = new CountDownLatch(8);         for (int i = 0; i < 8; i++) {             int finalI = i;             if (i == 5) {                 Thread.sleep(1000);                 new Thread(() -> {                     stopCarNotWait(semaphore, finalI);                     latch.countDown();                 }).start();                 continue;             }             new Thread(() -> {                 stopCarWait(semaphore, finalI);                 latch.countDown();             }).start();         }         latch.await();         log("总共还剩:" + semaphore.availablePermits() + "个车位");     }     private static void stopCarWait(Semaphore semaphore, int finalI) {         String format = String.format("车牌号%d", finalI);         try {             semaphore.acquire(1);             log(format + "找到车位了,去停车了");             Thread.sleep(10000);         } catch (Exception e) {             e.printStackTrace();         } finally {             semaphore.release(1);             log(format + "开走了");         }     }     private static void stopCarNotWait(Semaphore semaphore, int finalI) {          String format = String.format("车牌号%d", finalI);         try {             if (semaphore.tryAcquire()) {                 log(format + "找到车位了,WordPress模板去停车了");                 Thread.sleep(10000);                 log(format + "开走了");                 semaphore.release();             } else {                 log(format + "没有停车位了,不在这里等了去其他地方停车去了");             }         } catch (Exception e) {             e.printStackTrace();         }     }     public static void log(String content) {         // 格式化         DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");         // 当前时间         LocalDateTime now = LocalDateTime.now();         System.out.println(now.format(fmTime) + "  "+content);     } }  2021-03-01 18:54:57  车牌号0找到车位了,去停车了 2021-03-01 18:54:57  车牌号3找到车位了,去停车了 2021-03-01 18:54:57  车牌号2找到车位了,去停车了 2021-03-01 18:54:57  车牌号1找到车位了,去停车了 2021-03-01 18:54:57  车牌号4找到车位了,去停车了 2021-03-01 18:54:58  车牌号5没有停车位了,不在这里等了去其他地方停车去了 2021-03-01 18:55:07  车牌号7找到车位了,去停车了 2021-03-01 18:55:07  车牌号6找到车位了,去停车了 2021-03-01 18:55:07  车牌号2开走了 2021-03-01 18:55:07  车牌号0开走了 2021-03-01 18:55:07  车牌号3开走了 2021-03-01 18:55:07  车牌号4开走了 2021-03-01 18:55:07  车牌号1开走了 2021-03-01 18:55:17  车牌号7开走了 2021-03-01 18:55:17  车牌号6开走了 2021-03-01 18:55:17  总共还剩:5个车位 

从输出结果我们可以看到车牌号5这辆车看见没有车位了,就不在这个地方傻傻的等了,而是去其他地方了,但是车牌号6和车牌号7分别需要等到车库开出两辆车空出两个车位后才停进去。这就体现了Semaphore 的acquire 方法如果没有获取到凭证它就会阻塞,而tryAcquire方法如果没有获取到凭证不会阻塞的。

semaphore在dubbo中的应用

在Dubbo中可以给Provider配置线程池大小来控制系统提供服务的最大并行度,默认是200。

<dubbo:provider  threads="200"/> 

(责任编辑:应用开发)

推荐内容
  • 电脑赛博朋克素材教程(探索赛博朋克风格的电脑设计与创作技巧)
  • 「深入浅出」前端开发中常用的几种跨域解决方案
  • 如何更好的给CDN降本
  • 用python制作炫酷的滚动地球
  • 联想电脑新机使用教程(带你一步步了解联想电脑新机,让你成为电脑操作达人!)
  • Google开源Java字符编码检测工具介绍