分享一下最近优锐课学习笔记。

Java线程池执行程序偏向于排队而不是产生新线程。从好的方面来说,我们有两种解决方法。

理想情况下,对任何线程池执行程序而言,期望如下:

  • 预先创建了一组初始线程(核心线程池大小)来处理负载。
  • 如果负载增加,则应创建更多线程来处理最大线程数(最大池大小)的负载。
  • 如果线程数增加到“最大池大小”以外,则将任务排队。
  • 如果使用了有界队列,并且队列已满,请引入一些拒绝策略。

下图描述了该过程;仅创建初始线程来处理任务(负载很低时)。

随着更多的任务进入,假设创建的线程总数小于最大池大小,则会创建更多的线程来处理负载(任务队列仍然为空)。

如果任务总数大于线程总数(初始+扩展),则任务队列开始填充:

不幸的是,Java线程池执行器(TPE)偏向于排队而不是生成新线程,即,在初始核心线程被占用之后,任务被添加到队列中,并且在队列达到其限制之后(这只会在有界队列中发生) ),则会产生额外的线程。如果队列不受限制,则完全不会产生扩展线程,如下图所示。

  1. 创建了初始核心线程来处理负载。
  2. 一旦任务数量超过核心线程数,队列就会开始填满以存储任务。
  3. 队列填满后,将创建扩展线程。

这是TPE中的代码,出现了问题

我们有两种解决方法:

解决方法1:调整池大小

corePoolSize maximumPoolSize设置为相同的值,并将allowCoreThreadTimeOut 设置为true。

优点

  • 无需编码技巧。

缺点

  • 由于线程的创建和终止非常频繁,因此没有真正的线程缓存。
  • 没有适当的可伸缩性。

解决方法2:覆盖要约方法

  • 重写委托人TransferQueue的offer方法,并尝试将任务提供给空闲的工作线程之一。如果没有等待线程,则返回false。
  • 实现自定义RejectedExecutionHandler以始终添加到队列中。

实现自定义RejectedExecutionHandler以始终添加到位数中。

优点

  • TransferQueue确保不需要创建线程,并将工作直接转移到等待队列。

缺点

  • 不能使用定制的拒绝处理程序,因为它用于插入要排队的任务。

解决方法#3:使用自定义队列

使用自定义队列(TransferQueue)并覆盖offer方法以执行以下操作:

  1. 尝试将任务直接转移到等待队列(如果有)。
  2. 如果以上操作失败,并且未达到最大池大小,则通过从offer方法返回false来创建扩展线程。
  3. 否则,将其插入队列。

优点

  • TransferQueue确保不需要创建线程,并将工作直接转移到等待队列。
  • 可以使用自定义拒绝处理程序。

缺点

  • 队列和执行程序之间存在循环依赖关系。

解决方法4:使用自定义线程池执行程序

使用专门用于此目的的自定义线程池执行程序。它使用系统@ Facebook规模中所述的LIFO调度。

可扩展的Java线程池执行器的更多相关文章

  1. Netty核心概念(7)之Java线程池

    1.前言 本章本来要讲解Netty的线程模型的,但是由于其是基于Java线程池设计而封装的,所以我们先详细学习一下Java中的线程池的设计.之前也说过Netty5被放弃的原因之一就是forkjoin结 ...

  2. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

  3. 【转载】深度解读 java 线程池设计思想及源码实现

    总览 开篇来一些废话.下图是 java 线程池几个相关类的继承结构: 先简单说说这个继承结构,Executor 位于最顶层,也是最简单的,就一个 execute(Runnable runnable) ...

  4. Java并发指南12:深度解读 java 线程池设计思想及源码实现

    ​深度解读 java 线程池设计思想及源码实现 转自 https://javadoop.com/2017/09/05/java-thread-pool/hmsr=toutiao.io&utm_ ...

  5. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

  6. (转载)JAVA线程池管理

    平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...

  7. Java 线程池框架核心代码分析

    前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executor接口,提供了一种标准的方法将任务的提交过 ...

  8. Java线程池使用和分析(一)

    线程池是可以控制线程创建.释放,并通过某种策略尝试复用线程去执行任务的一种管理框架,从而实现线程资源与任务之间的一种平衡. 以下分析基于 JDK1.7 以下是本文的目录大纲: 一.线程池架构 二.Th ...

  9. 由浅入深理解Java线程池及线程池的如何使用

    前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...

随机推荐

  1. 在oracle数据库中创建DBLink

    涉及到两个数据库之间的访问时,可以创建datebase link来互相访问. ’创建方法: 1.通过PL/SQL客户端,找到datebase link,右键新建 输入相应信息 2.直接用命令行创建 一 ...

  2. 南开大学校徽及手写字的Tikz源码

    话不多说,直接上内容. % ---------------------------------- % !TeX enginee = pdfLaTeX/XeLaTeX % !TeX encoding = ...

  3. nyoj 3 多边形重心问题

    多边形重心问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 在某个多边形上,取n个点,这n个点顺序给出,按照给出顺序将相邻的点用直线连接, (第一个和最后一个连接 ...

  4. Grid表格的js触发事件

    没怎么接触过Grid插件: 解决的问题是:点击Grid表行里的内容触发js方法弹出模态框,用以显示选中内容的详细信息. 思路:给准备要触发的列加上一个css属性,通过这个css属性来获取元素并触发js ...

  5. opencv 4 图像处理 (1 线性滤波,非线性滤波)

    1 线性滤波:方框滤波.均值滤波.高斯滤波 1.1方框滤波(box Filter) 1.2均值滤波(blur函数) 缺陷: 1.3高斯滤波(GaussianBlur函数) 1.4线性滤波核心API函数 ...

  6. 区块链共识机制之工作量证明(POW)

    像比特币.以太坊.NXT.Bitshares等这些区块链系统,其本质上是一种加密经济组织,它建立在点对点网络上,是去中心化.无管辖的,由密码学.经济学和社会共识来共同维护.这些加密网络因各种原因有着多 ...

  7. Filebeat自定义索引 && 多output过滤

    一.目标 1)实现自定义索引 2)不同的input输出到各自对应的索引,nginx的日志输出到index-nginx的索引,zabbix的日志输出到index-zabbix,app的日志输出到inde ...

  8. Java流程控制之(二)循环

    目录 while循环 do..while循环 for循环 while循环和for循环基本概念--直接上代码! while循环 int i = 0; while(i<10) { System.ou ...

  9. Java方法之定义形式及可变参数

    目录 Java方法之定义形式及可变参数 方法调用 使用static修饰的方法 没有static修饰的方法 方法的定义格式 无参无返 无参有返 有参无返 有参有返 形参个数可变的方法 采用数组形参来定义 ...

  10. fastjson自定义序列化竟然有这么多姿势?

    本文介绍下fastjson自定义序列化的各种操作. 一.什么是fastjson? fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSO ...