Java中如何使用ReentrantLock实现长轮询
发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,这篇文章主要介绍"Java中如何使用ReentrantLock实现长轮询",在日常操作中,相信很多人在Java中如何使用ReentrantLock实现长轮询问题上存在疑惑,小编查阅了各式资料,整理出简
千家信息网最后更新 2025年01月20日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安全错误
数据库的锁怎样保障安全
亿图软件开发商
orcle数据库去除重复
东阳敏捷软件开发
电信与网络安全
mqtt连接多个服务器
济南直播软件开发价格
服务器需要关发动机
网络安全两单两卡
前端后端数据库交互过程
美国哪家公司做网络安全的
网络技术达人清风
idea连接远程服务器
数据库信息返回不到页面上
网络数据库加密技术的应用
服务器为什么会出问题
n1服务器繁忙
用服务器cpu 玩游戏
服务器数据丢失很久能恢复么
软件开发是流水线么
联想服务器管理口ip在哪看
无锡养老软件开发
水费网上缴费软件开发团队
中哈贸易数据库
网络安全女生学什么原因
软件开发项目工程特点
数据库上三角
为什么qq总提示服务器超时
oracle数据库倒库
华硕服务器cpu能用家用机吗
管家婆公司服务器