讲师中心 微信公众号
AI工具推荐 视频效率加速

Java多线程并发执行_Java线程并发执行控制方法

陌瑶姑娘_7674

陌瑶姑娘_7674

发布时间:2026-02-03 14:03:08

|

1069人浏览过

|

来源于php中文网

原创

应使用 ExecutorService 线程池替代手动 new Thread(),推荐显式构造 ThreadPoolExecutor 并配置有界队列与拒绝策略;批量任务用 invokeAll() 统一等待;共享状态优先用 AtomicInteger 或 ReentrantLock;ThreadLocal 必须手动 remove() 防泄漏。

java多线程并发执行_java线程并发执行控制方法

用 ExecutorService 替代手动 new Thread() 启动线程

手动 new Thread().start() 在并发量稍大时极易失控:线程数无节制增长、资源耗尽、OOM 频发。真正可控的并发执行必须走线程池。

推荐使用 Executors.newFixedThreadPool(n) 或更安全的显式构造方式:

ExecutorService pool = new ThreadPoolExecutor(
    4, 8, 60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100),
    new ThreadFactoryBuilder().setNameFormat("biz-task-%d").build(),
    new ThreadPoolExecutor.CallerRunsPolicy()
);
  • corePoolSize=4 表示常驻线程数,避免频繁创建销毁开销
  • maximumPoolSize=8 是峰值容量,配合有界队列防雪崩
  • CallerRunsPolicy 在队列满+线程达上限时,由提交线程自己执行任务,起到自然降级作用
  • 别用 Executors.newCachedThreadPool() —— 它的无界队列 + 60 秒空闲回收,在突发流量下会疯狂新建线程

并发任务结果聚合:用 invokeAll() 而非循环 submit() + get()

需要等一批任务全部完成并收集返回值?常见错误是逐个 submit() 再逐个 get(),这会串行等待,失去并发意义。

正确做法是批量提交后统一阻塞等待:

java-api-doc-generator
java-api-doc-generator

分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。

下载

立即学习“Java免费学习笔记(深入)”;

List<Callable<String>> tasks = Arrays.asList(
    () -> { Thread.sleep(100); return "A"; },
    () -> { Thread.sleep(200); return "B"; }
);
List<Future<String>> futures = pool.invokeAll(tasks, 5, TimeUnit.SECONDS); // 带超时
List<String> results = futures.stream()
    .map(f -> {
        try { return f.get(); } 
        catch (Exception e) { return null; }
    })
    .collect(Collectors.toList());
  • invokeAll() 保证所有任务并发启动,且整体超时控制(第二个参数)比单个 get(timeout) 更可靠
  • 若某任务抛异常或超时,对应 Future 的 get() 会抛 ExecutionException 或 TimeoutException,需捕获处理
  • 不要在 invokeAll() 后再调用 shutdown() —— 必须等所有 Future 处理完,否则可能中断未完成任务

共享状态写操作必须加锁:优先选 ReentrantLock 而非 synchronized

多个线程更新同一个计数器、缓存 Map 或 List,不加锁必然数据错乱。虽然 synchronized 最简单,但实际场景中往往需要更精细的控制。

比如要支持超时获取锁、可中断等待、或按条件唤醒特定线程:

private final ReentrantLock lock = new ReentrantLock();
private int counter = 0;

public void increment() {
    if (lock.tryLock(1, TimeUnit.SECONDS)) {
        try {
            counter++;
        } finally {
            lock.unlock();
        }
    } else {
        throw new RuntimeException("acquire lock timeout");
    }
}
  • tryLock(long, TimeUnit) 可避免无限阻塞,适合有 SLA 要求的服务
  • 用 lockInterruptibly() 支持线程被中断时及时退出,比 synchronized 更灵活
  • 对简单原子操作(如计数),优先用 AtomicInteger,它底层基于 CAS,无锁且性能更高
  • synchronized 不是不能用,但在需要响应中断、超时、或公平性策略时,ReentrantLock 是唯一选择

线程局部变量用 ThreadLocal,但务必手动 remove()

为避免传参污染,常把用户 ID、请求 traceId 存进 ThreadLocal。但 Web 容器(如 Tomcat)用线程池复用线程,不清理会导致内存泄漏和脏数据。

  • 永远在业务逻辑结束时调用 threadLocal.remove(),不要依赖 set(null)
  • 在 Filter / Interceptor 中统一 try-finally 清理,例如:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    try {
        MDC.put("traceId", generateTraceId());
        chain.doFilter(req, res);
    } finally {
        MDC.clear(); // 实际是 ThreadLocal.remove()
    }
}
  • 自定义 ThreadLocal 时,若值对象较大(如缓存的数据库连接),更要警惕内存泄漏
  • Spring 的 @Transactional、MyBatis 的 SqlSession 底层都重度依赖 ThreadLocal,所以事务失效、连接复用异常等问题,八成和没清理有关
线程模型不是加个 synchronized 就算并发安全,关键在资源生命周期管理——线程池大小、任务提交方式、锁粒度、上下文清理,每一步漏掉都会在高并发时暴露。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

相关专题

更多
如何配置Tomcat环境变量
如何配置Tomcat环境变量

配置Tomcat环境变量需要在系统中添加CATALINA_HOME变量,并将Tomcat的安装路径添加到PATH变量中。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

905

2023.10.26

idea如何集成Tomcat
idea如何集成Tomcat

idea集成Tomcat的步骤:1、添加Tomcat服务器配置;2、配置项目部署;3、运行Tomcat服务器;4、访问项目;5、注意事项;6、关闭Tomcat服务器。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

324

2024.02.23

怎么查看Tomcat源代码
怎么查看Tomcat源代码

查看Tomcat源代码的步骤:1、下载Tomcat源代码;2、在IDEA中导入Tomcat源代码;3、查看源代码;4、理解Tomcat的工作原理;5、参与社区和贡献;6、注意事项;7、持续学习和更新;8、使用工具和插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

489

2024.02.23

常见的tomcat漏洞有哪些
常见的tomcat漏洞有哪些

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

305

2024.02.23

tomcat日志乱码怎么解决
tomcat日志乱码怎么解决

tomcat日志乱码的解决办法:1、修改tomcat的日志编码设置;2、检查ide的编码设置;3、检查操作系统的编码设置;4、使用过滤器处理日志;5、检查外部系统的编码设置;6、检查文件编码方式等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

348

2024.02.23

weblogic和tomcat有哪些区别
weblogic和tomcat有哪些区别

weblogic和tomcat的区别:1、功能;2、性能;3、规模;4、价格;5、安全性;6、配置和管理;7、社区支持;8、集成能力;9、升级和更新;10、可靠性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

349

2024.02.23

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

601

2024.02.23

tomcat启动闪退怎么解决
tomcat启动闪退怎么解决

tomcat启动闪退的解决办法:1、检查java环境;2、检查环境变量配置;3、检查端口被占用;4、检查配置文件编码;5、检查启动时需要的配置文件;6、检查相关文件是否丢失;7、检查防火墙和杀毒软件设置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

322

2024.02.23

Docker Desktop怎么设置端口映射
Docker Desktop怎么设置端口映射

本专题聚焦Docker Desktop容器端口映射与访问配置,整理从创建容器、设置端口绑定到验证本地服务访问的操作流程。针对端口被占用、映射配置错误、容器服务无法访问等情况,也提供相应的检查方向,方便用户完成端口配置。

0

2026.11.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn