Java 线程池之Jetty 线程池学习总结

前提

Jetty 11.0.x

为什么是Jetty?

Java提供4中创建线程池的快捷方式

Executors.newFixedThreadPool();
Executors.newCachedThreadPool();
Executors.newSingleThreadExecutor();
Executors.newScheduledThreadPool();

但通常我们很少用这4个工厂方法去创建线程池,而是直接使用ThreadPoolExecutor类构造线程池,因为这些工厂方法最终也是调用这个类来创建线程池的。

众所周知,虽然ThreadPoolExecutor提供了corePoolSizemaximumPoolSize两个参数来控制线程池的基本大小和最大大小,但是这两个参数并不是那么好用:当任务队列采用SynchronousQueue时,通常需要无界的maximumPoolSize;当任务队列采用无界队列时,maximumPoolSize的值又相当于不起作用;当任务队列采用有界队列时,仅在任务队列已满,且未达到maximumPoolSize时才会扩充线程池大小。

既然如此,那有没有一种更简单的实现方案呢?使用该方案,使用者只需要简单的配置下线程池的基本大小和最大大小,程序就可以根据任务的繁忙程度自动调整当前线程数量。答案是有的:Jetty--一个基于Java的web容器,和Tomcat齐名

Jetty线程池介绍

任务处理流程

初始化线程池

程序初始化运行时,会先创建线程池,线程池大小默认为minThreads,也就是说会预先创建minThreads个线程,线程名称格式形如“qtp1076496284-13”

创建线程池时:

  • 如果未指定最大线程数(maxThreads),则默认为 200;

  • 如果未指定最小线程数(minThreads),则默认为 8

  • 如果未指定线程空闲超时时间(idleTimeout),则默认为 60000,即60秒

  • 保留线程数(reservedThreads)默认为 -1

  • 如果未指定任务队列,则默认创建BlockingArrayQueue任务队列,容量大小为 8 x 1024

  • 如果指定的最大线程数小于最小线程数,则抛出异常

线程池扩缩容

  • 当前线程数比最小线程数小,或者没有空闲的线程,且当前线程数(threads )小于最大线程数,则创建线程;
  • idleTimout大于0且当前线程数大于最小线程数,且线程空闲时间超过idleTimeout,则停止线程

注意:程序判断是否存在空闲线程的逻辑是这样的:Net空闲线程数 = 空闲线程数 - 任务队列大小,如果“Net空闲线程数”为负数,则表示不存在空闲线程,即需要更多的线程来处理任务。

任务队列及线程相关定义

queueSize 任务队列大小,即队列中等待被线程执行的任务数。可通过getQueueSize()函数获取。

threads 当前线程池中的线程数,包括已租给内部组件的线程、空闲线程、保留线程,以及正在执行临时作业的线程。threads = readyThreads + leasedThreads + utilizedThreads。 可通过getThreads() 函数获取。

readyThreads 准备执行临时任务的线程数。readyThreads = idleThreads + availableReservedThreads。可通过getReadyThreads()函数获取。

idleThreads 未被保留的空闲线程数。idleThreads = readyThreads - availableReservedThreads。可通过getIdleThreads()函数获取。

reservedThreads 保留的线程数,默认值为-1。可通过getReservedThreads()函数获取。

availableReservedThreads 可用的保留线程。可通过getAvailableReservedThreads()函数获取。

leasedThreads 供内部组件使用,用于执行内部任务的线程。需要线程的Jetty组件(比如网络acceptorsselector)可能会使用ThreadPoolBudget从线程池中租用线程。站在线程池的角度来看,这些被租用的线程是活跃的,但是不能用于执行临时任务,比如一个HTTP请求,或者一个WebSocket帧。QueuedThreadPool有一个ReservedThreadExecutor,该组件会从线程池租用线程,但会让这些线程可用,就像它们是“idle”线程一样。线程池启动后,该值一般是恒定的。可通过getLeasedThreads()函数获取。

minThreads 线程池中的最小线程数。可通过getMinThreads() 函数获取。

maxThreads 线程池中的最大线程数。可通过getMaxThreads() 函数获取。

maxAvailableThreads 可用于执行临时任务的最大线程数。maxAvailableThreads = maxThreads - leasedThreads 可通过getMaxAvailableThreads()函数获取。

utilizedThreads执行临时任务的线程数,可通过getUtilizedThreads()函数获取。utilizedThreads = threads - leasedThreads - readyThreads

utilizationRate = utilizedThreads / maxAvailableThreads 执行临时任务的线程利用率。该值为0.0D则表示线程池未被利用,如果为1.0D则表示线程池被充分利用于执行临时任务。可通过getUtilizationRate() 函数获取。

busyThreads 正在执行内部任务和临时任务的线程数。 busyThreads = utilizedThreads + leasedThreads。可通过getBusyThreads()函数获取。

参考链接

https://www.eclipse.org/jetty/javadoc/jetty-11/org/eclipse/jetty/util/thread/QueuedThreadPool.html

https://gitee.com/Tedgar156/jetty.project/blob/jetty-11.0.x/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java

Java 线程池之Jetty 线程池学习总结的更多相关文章

  1. Java 线程池的原理与实现学习(三)

    一简介 线程的使用在java中占有极其重要的地位,jdk1.4及其之前的jdk版本,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观,Jdk1.5之后加入了java.util.c ...

  2. Java 线程池的原理与实现学习(二)

    java类库中提供的线程池简介: java提供的线程池更加强大,相信理解线程池的工作原理,看类库中的线程池就不会感到陌生了. execute(Runnable command):履行Ruannable ...

  3. Java 线程池的原理与实现学习(一)

    线程池:多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.    假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中 ...

  4. 转:Java Web应用中调优线程池的重要性

    不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文主要介绍Java线程池的使用和如何正确的配置线程 ...

  5. Java Web应用调优线程池

    最简单的单线程 我们先从基础开始.无论使用哪种应用服务器或者框架(如Tomcat.Jetty等),他们都有类似的基础实现.Web服务的基础是套接字(socket),套接字负责监听端口,等待TCP连接, ...

  6. Java Web应用中调优线程池的重要性

    不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文主要介绍Java线程池的使用和如何正确的配置线程 ...

  7. 【java】之常用四大线程池用法以及ThreadPoolExecutor详解

    为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率2.线程并发数量过多,抢占系统资源从而导致阻塞3.对线程进行一些简单的管理 在Java中,线程池 ...

  8. java线程一之创建线程、线程池以及多线程运行时间统计

    线程和进程的基本概念 进程和线程是动态的概念.         进程是 "执行中的程序",是一个动词,而程序是一个名词,进程运行中程序的"代码",而且还有自己的 ...

  9. java基础(26):Thread、线程创建、线程池

    1. 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并 ...

  10. Java 线程池中的线程复用是如何实现的?

    前几天,技术群里有个群友问了一个关于线程池的问题,内容如图所示: 关于线程池相关知识可以先看下这篇:为什么阿里巴巴Java开发手册中强制要求线程池不允许使用Executors创建? 那么就来和大家探讨 ...

随机推荐

  1. AI实战 | 手把手带你打造校园生活助手

    大家好,我是努力的小雨.最近,我开始将我的经验逐渐分享到B站,希望能够帮助大家通过扣子助手真正解决一些问题.最近有粉丝提出了一个需求,为了满足大家的期待,我已经制作了视频,详细介绍了这个助手的搭建思路 ...

  2. PaddleOCR之高性能Go语言实现OCR识别

    最近为了让python语言能够直接调用PaddleOCR的C++的动态链接库,针对本人已经开源的PaddleOCR项目https://gitee.com/raoyutian/paddle-ocrsha ...

  3. NOIP模拟70

    T1 暴雨 解题思路 \(f_{i,j,k,0/1}\) 表示前 i 个铲平 j 个当前最高的是 k 并且当前是 奇数/偶数 的方案数. 由于只可以铲平 k 块,因此对于同一种 \(i,j\) 而言高 ...

  4. CF364E

    problem 算法1 我会暴力!!! 直接枚举右上角和左下角,然后计算答案,使用前缀和优化后时间复杂度为 \(O(n^4)\). 算法2 我会分治!!!. 我们知道答案就是左边+右边+两边都有的个数 ...

  5. m3u8文件转换mp4 ffmpeg

    m3u8文件转换mp4 ffmpeg 命令行执行下面语句: ffmpeg -i input.m3u8 -c copy output.mp4 ffmpeg.exe 和 input.m3u8 放在同一目录 ...

  6. Math.ceil,Math.round,Math.floor区别

    Math.ceil,Math.round,Math.floor区别 //向上取整 System.out.println("amt1=" + Math.ceil(71.01)); / ...

  7. CNN -- Simple Residual Network

    Smiling & Weeping ---- 我爱你,从这里一直到月亮,再绕回来 说明: 1.要解决的问题:梯度消失 2. 跳连接,H(x) = F(x)+x,张量维度必须一致,加完后再激活. ...

  8. Python_9 py文件导入和路径处理

    一.查缺补漏 Python中两个值交换可以直接交换如:a,b=b,a 冒泡就是从小到大排序,因为越到后越大 自动导包也适用于自己创建的模块 关于正斜杠和反斜杠https://www.cnblogs.c ...

  9. FFmpeg开发笔记(三十三)分析ZLMediaKit对H.264流的插帧操作

    ​<FFmpeg开发实战:从零基础到短视频上线>一书的"3.4.3  把原始的H264文件封装为MP4格式"介绍了如何把H.264裸流封装为MP4文件.那么在网络上传输 ...

  10. Fake权限验证小例子

    前言 关于本地测试如何进行Fake权限验证 正文 在我们使用swagger调试本地接口的时候,我们常常因为每次需要填写token而耽误工作,不可能每次调试的时候都去本地测试环境请求一个token进行验 ...