热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

线程池正确用法

背景 对于java开发从业人员来说,并发编程是绕不开的话题,juc并发包下提供了一系列多线程场景解决方案。 随着jdk1.8的普及,多线程处理问题,除了使用使用线程池(Execut

背景

 对于java开发从业人员来说,并发编程是绕不开的话题,juc并发包下提供了一系列多线程场景解决方案。
 随着jdk1.8的普及,多线程处理问题,除了使用使用线程池(ExecutorService),很多人选择了parallelStream() 并行流,底层使用forkjoin实现并行处理。
 那么并行和并发又有什么区别?究竟改如何选择?滥用时又会有什么影响?
  这些问题我分以下几篇文章进行详细说明:
  1. 多线程并发和并行的区别
  2. parallelStream()并行滥用的后果
  3. forkjoin和forkjoinpool讲解
  4. 线程池正确用法(本文)

为什么用线程池

  • 用线程池之前有一个问题,就是为什么用多线程?
    由于io等待存在,单线程在web开发上是对cpu极大的浪费(tomcat就是线程池的),多线程是必须的。
  • 线程池解决的问题
  1. 减小线程池创建和销毁销毁的性能(java线程是内核创建)
  2. 线程池提供了队列,当任务多时可以合理使用cpu和内存
  3. 线程池提供定时调用功能
  4. 线程池提供拒绝策略, 超过预定符合时,可以执行预定逻辑
    以上这些都是直接使用多线程很难实现的。

线程池参数说明

Alibaba的p3c规范中,不建议使用系统默认的4中线程池。以下是创建线程池的参数列表,
《线程池正确用法》

public ThreadPoolExecutor(
int corePoolSize, //第1个参数
int maximumPoolSize, //第2个参数
long keepAliveTime, //第3个参数
TimeUnit unit, //第4个参数
BlockingQueue<Runnable> workQueue, //第5个参数
ThreadFactory threadFactory, //第6个参数
RejectedExecutionHandler handler //第7个参数
)

  • 第1个参数 :corePoolSize 表示常驻核心线程数。如果等于0,则任务执行完成后,没有任何请求进入时销毁线程池的线程;如果大于0,即使本地任务执行完毕,核心线程也不会被销毁。这个值的设置非常关键,设置过大会浪费资源,设置的过小会导致线程频繁地创建或销毁。
  • 第2个参数:maximumPoolSize 表示线程池能够容纳同时执行的最大线程数。从上方的示例代码中第一处来看,必须大于或等于1。如果待执行的线程数大于此值,需要借助第5个参数的帮助。缓存在队列中。如果maximumPoolSize 与corePoolSize 相等,即是固定大小线程池。
  • 第3个参数:keepAliveTime 表示线程池中的线程空闲时间,当空闲时间达到KeepAliveTime 值时,线程被销毁,直到剩下corePoolSize 个线程为止,避免浪费内存和句柄资源。在默认情况下,当线程池的线程大于corePoolSize 时,keepAliveTime 才会起作用。但是ThreadPoolExecutor的allowCoreThreadTimeOut 变量设置为ture时,核心线程超时后也会被回收。
  • 第4个参数:TimeUnit 表示时间单位。keepAliveTime 的时间单位通常是TimeUnit.SECONDS。
  • 第5个参数: workQueue 表示缓存队列。当请求的线程数大于maximumPoolSize时,线程进入BlockingQueue 阻塞队列。后续示例代码中使用的LinkedBlockingQueue 是单向链表,使用锁来控制入队和出对的原子性,两个锁分别控制元素的添加和获取,是一个生产消费模型队列。
  • 第6个参数:threadFactory 表示线程工厂。它用来生产一组相同任务的线程。线程池的命名是通过给这个factory增加组名前缀来实现的。在虚拟机栈分析时,就可以知道线程任务是由哪个线程工厂产生的。
  • 第7个参数:handler 表示执行拒绝策略的对象。当超过第5个参数workQueue的任务缓存区上限的时候,就可以通过该策略处理请求,这是一种简单的限流保护。友好的拒绝策略可以使如下三种:
    1. 保存到数据库进行削峰填谷。在空闲的时候再拿出来执行。
    2. 转向某个提示页面。
    3. 打印日志。

线程池使用注意事项

  1. 线程池中使用ThreadLocal时,一定要记得remove。否则线程重复使用,会获取到上次执行残留的ThreadLocal
  2. 合理设置线程池和等待队列的大小
    • 线程池太小无法有效利用cpu
    • 线程池过大,会浪费内存,并且cpu切换消耗时间
    • 根据当前业务量设置workQueue的大小
  3. 避免线程池创建和释放的滥用
    线程池尽量使用工具类后者项目初始化时创建,避免业务每次请求都创建线程池,这样线程池既没有启动节省资源作用,反而没有合理释放,浪费资源。

推荐阅读
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • Java项目分层架构设计与实践
    本文探讨了Java项目中应用分层的最佳实践,不仅介绍了常见的三层架构(Controller、Service、DAO),还深入分析了各层的职责划分及优化建议。通过合理的分层设计,可以提高代码的可维护性、扩展性和团队协作效率。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • Linux系统中Java程序Too Many Open Files问题的深入解析与解决方案
    本文详细分析了在Linux环境下运行的Java应用程序中可能出现的“Too many open files”异常现象,探讨其成因及解决方法。该问题通常出现在高并发文件访问或大量网络连接场景下,对系统性能和稳定性有较大影响。 ... [详细]
  • 全面解析运维监控:白盒与黑盒监控及四大黄金指标
    本文深入探讨了白盒和黑盒监控的概念,以及它们在系统监控中的应用。通过详细分析基础监控和业务监控的不同采集方法,结合四个黄金指标的解读,帮助读者更好地理解和实施有效的监控策略。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 本文详细介绍了如何在 MySQL 中授予和撤销用户权限。包括创建用户、赋予不同级别的权限(如表级、数据库级、服务器级)、使权限生效、查看用户权限以及撤销权限的方法。此外,还提供了常见错误及其解决方法。 ... [详细]
  • 本文详细探讨了JavaScript中的作用域链和闭包机制,解释了它们的工作原理及其在实际编程中的应用。通过具体的代码示例,帮助读者更好地理解和掌握这些概念。 ... [详细]
  • 深入理解 .NET 中的中间件
    中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
  • Java多线程实现:从1到100分段求和并汇总结果
    本文介绍如何使用Java编写一个程序,通过10个线程分别计算不同区间的和,并最终汇总所有线程的结果。每个线程负责计算一段连续的整数之和,最后将所有线程的结果相加。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 本文详细探讨了Java中Volatile关键字的工作原理、优化技巧及其在实际开发中的应用场景,特别是在提高多线程环境下数据可见性和减少锁竞争方面的优势。 ... [详细]
  • 字节跳动夏季招聘面试经验分享
    本文详细记录了字节跳动夏季招聘的面试经历,涵盖了一、二、三轮面试的技术问题及项目讨论,旨在为准备类似面试的求职者提供参考。 ... [详细]
author-avatar
mobiledu2502892183
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有