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

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. [LC]876题 Middle of the Linked List (链表的中间结点)(链表)

    ①中文题目 给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3,4,5]输出:此列表中的结点 3 (序列化形式 ...

  2. open-falcon监控系统

    官方文档 https://book.open-falcon.org/zh/intro/index.html 一.Open-Falcon介绍 1.监控系统,可以从运营级别(基本配置即可),以及应用级别( ...

  3. nyoj 18-The Triangle(动态规划)

    18-The Triangle 内存限制:64MB 时间限制:1000ms Special Judge: No accepted:5 submit:5 题目描述: 7 3 8 8 1 0 2 7 4 ...

  4. nyoj 64-鸡兔同笼 (解二元一次方程)

    64-鸡兔同笼 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:26 submit:58 题目描述: 已知鸡和兔的总数量为n,总腿数为m.输入n和m, ...

  5. python:正则1

    鱼c(扩展阅读): Python3 如何优雅地使用正则表达式(详解一) Python3 如何优雅地使用正则表达式(详解二) Python3 如何优雅地使用正则表达式(详解三) Python3 如何优雅 ...

  6. opencv 4 图像处理(漫水填充,图像金字塔与图片尺寸缩放,阈(yu)值化)

    漫水填充 实现漫水填充算法:floodFill函数 简单调用范例 #include <opencv2/opencv.hpp> #include <opencv2/imgproc/im ...

  7. 概率的基本概念&离散型随机变量

    使用excel可以直接计算二项分布和超几何分布:

  8. python_07

    破解极限滑动认证 from selenium import webdriver from selenium.webdriver import ActionChains from PIL import ...

  9. [ch04-01] 用最小二乘法解决线性回归问题

    系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 4.1 最小二乘法 4.1.1 历史 最小二乘法,也叫做 ...

  10. 解决Mybatis-plus高版本不向后兼容的问题

    mybatis-plus插件后面的版本没有兼容低版本.即:不存在低版本中EntityWrapper这个类了.而该类采用数据库表真实字段名作查询条件,这样硬编码形式确实不友好,比如如果后面数据库表中字段 ...