千家信息网

LimitLatch在Tomcat 中的应用是怎样的

发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,这篇文章给大家介绍LimitLatch在Tomcat 中的应用是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Tomcat的LimitLatch类用于控制网络通信的sock
千家信息网最后更新 2025年12月01日LimitLatch在Tomcat 中的应用是怎样的

这篇文章给大家介绍LimitLatch在Tomcat 中的应用是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

Tomcat的LimitLatch类用于控制网络通信的socket接收上限,在Tomcat7时引入,实现简单,借此可以学习一下线程同步的相关知识。

LimitLatch依赖内部类Sync进行线程同步,而Sync继承自大家熟悉的AbstractQueuedSynchronizer。AQS是java.util.concurrent的核心组件,诸多常用的线程同步工具类都能够找到他的影子,读者可以翻阅ReentrantLock、CountDownLatch、Semaphore等类的源码。

//if we have reached max connections, wait

countUpOrAwaitConnection();

SocketChannel socket = null;

try {

// Accept the next incoming connection from the server socket

socket = serverSock.accept();

……

不管是NIO还是BIO,Tomcat在接收socket前,都要通过countUpOrAwaitConnection方法获取资源,如果已经达到最大连接数,则需要当前线程等待资源释放。该方法最终会调用到LimitLatch的内部类Sync的acquireSharedInterruptibly方法,即AQSacquireSharedInterruptibly方法。

从内部类Sync的重载方法我们能看到Sync是一个共享模式的同步器,重载了tryAcquireShared和tryReleaseShared两个方法,而两个方法之所以能够如此简单,就是因为父类AQS在背后默默完成了其他所有的排队、等待、激活等一系列逻辑。

protected int tryAcquireShared(int ignored) {

long newCount = count.incrementAndGet();

if (!released && newCount > limit) {//自增后没有超过资源上限则获取成功 // Limit exceeded

count.decrementAndGet();//资源获取失败,回退

return -1;

} else {

return 1;

}

}

在获取共享资源时,LimitLatch.Sync使用了原子变量AtomicLong,利用其自增的CAS原子操作结果与设定的共享资源数量上限进行比较,如果超出上限则目前无法获取资源,由AQS放入等待队列等待下次触发。LimitLatch中定义了released属性,该属性为true时,无论如何都会获取到共享资源。

public boolean releaseAll() {

released = true;//标志位置为ture后,后续均可获取资源

return sync.releaseShared(0);//通知等待线程重新获取资源

}

这里就有一个问题了,既然无论如何都会获取到资源,LimitLatch就没有存在的必要,那为何还要这样一个看似多余的released 属性呢?这里其实考虑到一个状态变更的问题,当由一个LimitLatch控制资源获取量变更为无需LimitLatch时,仅仅将LimitLatch置为null从而跳过资源竞争是不够的。

如果之前存在在等待队列中等待资源的线程,而此时没有资源释放,那么在状态变更后线程仍然会处于等待状态,这与"无限制"的状态是不符的,此时需要将released属性置为true,然后通过一次资源释放由AQS触发所有等待线程重新获取资源,这个时候所有线程均会获取资源立即返回。

protected boolean tryReleaseShared(int arg) {

count.decrementAndGet();//自减释放资源

return true;

}

资源释放时的代码就更简单了,直接将代表资源的原子变量AtomicLong自减从而释放资源就完成了。而后续的唤醒等待资源的线程等工作已经由AQS代劳了。

写到这里,问题又来了,这个功能完全可以由JDK自带的Semaphore类来完成啊。如果非要再写一个那一定是因为性能的原因了,毕竟该类要使用在接收Socket的前面,对性能有直接影响。下面代码为Semaphore类(JDK1.8)的FairSync重写的tryAcquireShared方法,本质上与LimitLatch并无什么不同,都是CAS自旋:

protected int tryAcquireShared(int acquires) {

for (;;) {

if (hasQueuedPredecessors())

return -1;

int available = getState();

int remaining = available - acquires;

if (remaining < 0 || compareAndSetState(available, remaining))

return remaining;

}

}

话不多说,开始性能测试,测试场景分为64线程竞争64个资源以及64线程竞争32个资源,循环300w次。测试结果竟然是LimitLatch性能要比Semaphore性能低近10%左右,这个。。。一定是我打开的方式不对。

关于LimitLatch在Tomcat 中的应用是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

资源 线程 方法 性能 上限 属性 状态 同步 共享资源 原子 问题 测试 竞争 应用 无论如何 两个 代码 内容 变量 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 江北区水利数据库招标 进销存数据库 下载 软件开发项目视频教程 苹果关闭了验证服务器 预防无线网络安全 数据库安全性的不足之处 网络安全支付中存在的问题 广德智能软件开发服务品质保障 青芷柠源神奇宝贝服务器怎么下载 页面向数据库插入数据php 泰拉瑞亚手机好玩的服务器 无人收银软件开发 廊坊市捷讯网络技术 上海私有服务器价格 数据库中建物理模型的工具 连接远程数据库tns串的使用 思腾合力服务器是国内产的吗 查看数据库列表的命令语句什么 怎么查自己家网络服务器地址 网络安全手抄报能看清的 网络安全的三岁药 什么叫互联网高科技公司 条件查询数据库表sql 网络安全危害多课堂实录 网络安全竞赛总结报告 廊坊市捷讯网络技术 光猫服务器名称怎么查 mysql建数据库工具 选择题 数据库管理系统 万方数据库的外部特征
0