长连接中异步任务的同步等待陷阱:一次主线程阻塞的排查与修复

最近的项目出现了一个bug,长连接中使用了异步线程池,具体是有一个循环,每一次循环都用了异步线程,然后呢,在长连接中处理这个循环的同时,还会有前端向后端发送消息,那么后端也要接收相应的消息进行处理,每次循环的异步线程如下

java 复制代码
Future<Boolean> submit = taskExecutor.submit(new Callable<Boolean>() {
                @Override
                public Boolean call(){}
                });

然后呢还搞了一个

java 复制代码
private final Map<String, Future<Boolean>> Futures = new ConcurrentHashMap<>();
Futures.put(id, submit);

以id为key保存每一次循环中的异步线程返回值,然后呢,最灵魂的代码来喽,这句代码真是给添了不少麻烦,那就是等待这次异步任务完成,实际上大错特错

java 复制代码
Future<Boolean> future = Futures.get(id);
Boolean b = future.get();

这句代码乍一看倒是没什么问题,但是呢,在运行的时候,前端向后端发送特定的消息,后端没有响应,哇靠,这是为啥嘞?

没错,就是Boolean b = future.get();把主线程给阻塞了,导致不能处理其他问题,其实这只是一个小问题哈,但是有时候往往是小问题在写代码的时候,加着加着就忘记了,结果排查的时候好半天才看到。

最后的解决办法是啥呢,最后搞了一个异步线程处理这个循环,大致的代码示意如下:

java 复制代码
 CompletableFuture.runAsync(()->
    {
        for (dto:list) {
            Future<Boolean> submit = taskExecutor.submit(new Callable<Boolean>() {
                @Override
                public Boolean call() {
                }
            });
        }
    })
相关推荐
liuchangng12 小时前
Jev 模型研究:从生成式大模型到决策式模型——System One、RLCD 校准与采用边界
java·javascript·人工智能·python·深度学习
GPU实战笔记12 小时前
本地跑不动 llama.cpp,临时租云 GPU 怎么搭?从启动服务到环境复用
java·服务器·网络·人工智能·深度学习·llama
撸串-研究生12 小时前
SSM + Vue 线上作业批改系统:在线答题、文件提交与教师批改闭环90608
java·ssm·在线答题·作业批改·文件提交
一 乐12 小时前
养老院管理系统|基于springboot + vue养老院管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
wang_shu_mo_ran12 小时前
Spring MVC 常用注解和用法(二)——url,cookie,session
java·mvc
杨运交12 小时前
[074][示例]基于Redisson的分布式锁在定时任务中的实践与异常模拟
java·后端·spring
小刘在重生~12 小时前
Java Lock 显式锁案例|ReentrantLock 解决多线程安全问题(超详细实战)
java·笔记·面试
步行cgn12 小时前
Spring 中完整的 Scope 选项详解
java·后端·spring
hai_android13 小时前
Android MeasureSpec 详解
android·java·kotlin
阳光宅男@李光熠14 小时前
【电子通识】一起学习TDK的EMC基础——电池兼容设计方法概述
java·前端·数据库