千家信息网

如何通过ThreadPoolExecutor的方式创建线程池

发表于:2024-11-25 作者:千家信息网编辑
千家信息网最后更新 2024年11月25日,如何通过ThreadPoolExecutor的方式创建线程池,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。线程池不建议使用Execu
千家信息网最后更新 2024年11月25日如何通过ThreadPoolExecutor的方式创建线程池

如何通过ThreadPoolExecutor的方式创建线程池,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

线程池不建议使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

Executors各个方法的弊端:

  1. newFixedThreadPool 和 newSingleThreadExecutor:
    主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。(笔者注:阻塞队列均采用LinkedBlockingQueue)

  2. newCachedThreadPool 和 newScheduledThreadPool:
    主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

ThreadPoolExecutor函数

Executors提供了四种创建线程池的方法,实际上Executors的底层也是调用了ThreadPoolExecutor。函数定义如下:

public ThreadPoolExecutor(int corePoolSize,  // 线程池的核心线程数                          int maximumPoolSize, // 线程池的最大线程数                          long keepAliveTime, // 当线程数大于核心时,多余的空闲线程等待新任务的存活时间。                          TimeUnit unit, // keepAliveTime的时间单位                          ThreadFactory threadFactory, // 线程工厂                          BlockingQueue workQueue,// 用来储存等待执行任务的队列                          RejectedExecutionHandler handler // 拒绝策略                          )

线程池运行原理:

函数参数补充说明

  1. workQueue有以下七种选择:

  • ArrayBlockingQueue: 一个由数组结构组成的有界阻塞队列(数组结构可配合指针实现一个环形队列)。

  • LinkedBlockingQueue: 一个由链表结构组成的有界阻塞队列,而在未指明容量时,容量默认为Integer.MAX_VALUE。

  • PriorityBlockingQueue: 一个支持优先级排序的无界阻塞队列,对元素没有要求,可以实现Comparable接口也可以提供Comparator来对队列中的元素进行比较,跟时间没有任何关系,仅仅是按照优先级取任务。

  • DelayQueue: 同PriorityBlockingQueue,也是二叉堆实现的优先级主阻塞队列。要求元素都实现Delayed接口,通过执行时延从队列中提取任务,时间没到任务取不出来。

  • SynchronousQueue: 一个不存储元素的阻塞队列,消费者线程调用take()方法的时候就会发生阻塞,直到有一个生产者线程生产了一个元素,消费者线程就可以拿到这个元素并返回;生产者线程调用put()方法的时候就会发生阻塞,直到有一个消费者线程消费了一个元素,生产者才会返回。

  • LinkedTransferQueue: 它是ConcurrentLinkedQueue、LinkedBlockingQueue和SynchronousQueue的结合体,但是把它用在ThreadPoolExecutor中,和LinkedBlockingQueue行为一致。

  • LinkedBlockingDeque: 使用双向队列实现的双端阻塞队列,双端意味着可以像普通队列一样FIFO(先进先出),可以以像栈一样FILO(先进后出)

  1. handler有以下四种取值:

  • AbortPolicy(默认):丢弃任务并抛出RejectedExecutionException异常。

  • CallerRunsPolicy:由调用线程处理该任务。(例如io操作,线程消费速度没有NIO读取快,可能导致阻塞队列一直增加,此时可以使用这个模式)

  • DiscardPolicy:丢弃任务,但是不抛出异常。 (可以配合这种模式进行自定义的处理方式)

  • DiscardOldestPolicy:丢弃队列最早的未处理任务,然后重新尝试执行任务(重复执行)

关于如何通过ThreadPoolExecutor的方式创建线程池问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

线程 队列 任务 阻塞 元素 方式 方法 问题 处理 消费 时间 生产 优先级 函数 消费者 生产者 结构 最大 先进 容量 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中邦网络安全技术(深圳)有限公司 用友数据库讲解 冬奥会铁路网络安全重要性 盛天网络技术有限公司 糗事百科服务器升级 杨浦区个人数据库研发价格大全 中企守信网络技术有 吉林pdu服务器电源制造商 学习通课程为什么连接服务器失败 光明大陆官网服务器 招聘网络安全博士的中国大学 足球数据库技术分析 赛季服哪些服务器开了安琪拉 网络安全队伍技术专业 新乡华申网络技术有限公司 京台高速台儿庄大运河服务器 信息网络安全管理控制 机房工程机柜及服务器柜设计方案 美团软件开发工程师赵越 isc共探企业网络安全 数据库只有7个表的blog系统 软件开发 平台化 汽车 网络安全中国战略发展趋势 苏州软件开发专业公司 云南服务器机柜直销价格 个人网络安全防范措施 咸鱼之王怎么切换服务器 JAVA软件开发需要考证吗 网络安全的宣传标题 河南网络服务器机箱供应云主机
0