Java中如何使用ReentrantLock实现长轮询
发表于:2025-02-24 作者:千家信息网编辑
千家信息网最后更新 2025年02月24日,这篇文章主要介绍"Java中如何使用ReentrantLock实现长轮询",在日常操作中,相信很多人在Java中如何使用ReentrantLock实现长轮询问题上存在疑惑,小编查阅了各式资料,整理出简
千家信息网最后更新 2025年02月24日Java中如何使用ReentrantLock实现长轮询
这篇文章主要介绍"Java中如何使用ReentrantLock实现长轮询",在日常操作中,相信很多人在Java中如何使用ReentrantLock实现长轮询问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Java中如何使用ReentrantLock实现长轮询"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
Java代码
1. ReentrantLock
加锁阻塞,一个condition对应一个线程,以便于唤醒时使用该condition一定会唤醒该线程
/** * 获取探测点数据,长轮询实现 * @param messageId * @return */ public JSONObject getToutData(String messageId) { Message message = toutMessageCache.get(messageId); if (message == null) { // 等待 lock.lock(); try { Condition condition = lock.newCondition(); conditionMap.put(messageId + "_data", condition); condition.await(CONNECTION_HOLD_TIMEOUT, TimeUnit.SECONDS); // 等待60s } catch (InterruptedException e) { // 等待超时, do nothing } finally { lock.unlock(); } } // 再次尝试获取 message = toutMessageCache.get(messageId); if (message == null) { // 如果还没有, 返回空对象 return null; } byte[] bytes = message.getDataBytes(); if (bytes == null) { return null; } String resStr = new String(bytes, StandardCharsets.UTF_8);// log.info("resStr: {}", resStr); JSONObject resObj; try { resObj = new JSONObject(resStr); resObj.put("invokeTime", DateUtil.format(new Date(resObj.getLong("invokeTime")), DatePattern.NORM_DATETIME_MS_PATTERN)); } catch (Exception e) { resObj = new JSONObject(); } return resObj; }
2. 回调
当异步数据返回,使用上一步的condition唤醒线程
public void callback(Message message) { String messageId = message.getId(); toutMessageCache.put(message.getId(), message); String messageDataId = messageId + "_data"; if (conditionMap.containsKey(messageDataId)) { lock.lock(); try { Condition condition = conditionMap.get(messageDataId); condition.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); conditionMap.remove(messageDataId); } }}
3. 唤醒
执行回调操作
public void distribute(Message message, ChannelHandlerContext ctx) { MessageType messageType = message.getMessageType(); switch (messageType) { case TOUT_DATA_RESPONSE: // 数据响应 toutService.callback(message); break; }}
4. 调用
调用时,判断返回的值是否为空,如果为空,与前端约定,当返回该状态值时,应再次发起相同请求
/*** 获取探测数据(使用长轮询实现)* @param linkId* @return*/@GetMapping("/data")public ResultVO getToutData(String linkId) { JSONObject resObj = toutService.getToutData(linkId); if (resObj == null || resObj.isEmpty()) { return ResultVOUtil.error(ResultEnum.NO_MESSAGE_HOLD_CONNECTION); } return ResultVOUtil.success(resObj);}
5.前端实现
简单使用递归实现了当数据返回无效时再次发起请求
let that = thisfunction getData() { if (toutStatus === statusEnum.start) { getToutData({ linkId }).then(res => { if (res.code === ERROR_CODE_OK) { that.toutData = res.data toutStatus = statusEnum.resData that._btnStatus() } else { getData() } }) } } // 递归循环调用 getData()
到此,关于"Java中如何使用ReentrantLock实现长轮询"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
数据
学习
再次
线程
前端
更多
递归
帮助
探测
实用
相同
接下来
代码
对象
文章
方法
状态
状态值
理论
知识
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
文件服务器 java
中国数字网络安全刘新华
网络安全事件分哪几类
我的世界青花服务器
黄浦区一站式软件开发成本价
深圳中易通网络技术
石家庄服务器托管公司
迅雷离线服务器配置
软件开发费用明细
二手 服务器 SAS 2T硬盘
如何在我的世界里面建造服务器
数据库并发一致性
多台云服务器管理办法
计算机网络技术专业薪酬怎么样
贵阳云刚软件开发中心
押大小游戏软件开发
河南指阅网络技术有限责任公司
上海银庭网络技术怎么样
金融行业数据库小数据存储
做网站怎样可以看到哪里的服务器
减少冗余的技术数据库技术
网络安全漫画手绘儿童
国家网络安全应急管理部地址
数据库怎样为约束规则命名
创建数据库中的数据表结构
手机原神切换服务器
蓟州区数据网络技术不二之选
网络安全可行研究报告
数据库驱动程序是什么
dell服务器r740专业定制