带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(6)

简介: 带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(6)

带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(5)https://developer.aliyun.com/article/1340064?groupCode=taobaotech

image.pngTomcat自定义任务队列

 

 

在Tomcat中重新定义了一个阻塞队列TaskQueue,它继承于LinkedBlockingQueue。在Tomcat中,核心线程 数默认值为10,最大线程数默认为200,为了避免线程到达核心线程数后后续任务放入队列等待,Tomcat通过自 定义任务队列TaskQueue重写offer方法实现了核心线程池数达到配置数后线程的创建。

 

具体地,从线程池任务调度机制实现可知,当offer方法返回false时,线程池将尝试创建新新线程,从而实现任务的   快速响应。TaskQueue核心实现代码如下:

 

 

/**
*As task queue specifically designed to run with a thread pool executor. The
*task queue is optimised to properly utilize threads within a thread pool
*executor. If you use a normal queue, the executor will spawn threads when
*there are idle threads and you wont be able to force items onto the queue
*itself.
*/
public class TaskQueue extends LinkedBlockingQueue<Runnable> {
public boolean force(Runnable o, long timeout, TimeUnit unit) throws InterruptedException {
if ( parent==null || parent.isShutdown() ) throw new RejectedExecutionException("Executor not running, can't force a command into the queue");


12

 

return super.offer(o,timeout,unit); //forces the item onto the queue, to be used if the task is rejected

13

 

}

14

 

 

15

 

@Override

16

 

public boolean offer(Runnable o) {

17

 

// 1. parent为线程池,Tomcat中为自定义线程池实例

18

 

//we can't do any checks

19

 

if (parent==null) return super.offer(o);

20

 

// 2. 当线程数达到最大线程数时,新提交任务入队

21

 

//we are maxed out on threads, simply queue the object

22

 

if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o);

23

 

// 3. 当提交的任务数小于线程池中已有的线程数时,即有空闲线程,任务入队即可

24

 

//we have idle threads, just add it to the queue

25

 

if (parent.getSubmittedCount()<=(parent.getPoolSize())) return super.offer(o);

26

 

// 4. 【关键点】如果当前线程数量未达到最大线程数,直接返回false,让线程池创建新线程

27

 

//if we have less threads than maximum force creation of a new thread

28

 

if (parent.getPoolSize()<parent.getMaximumPoolSize()) return false;

29

 

// 5. 最后的兜底,放入队列

30

 

//if we reached here, we need to add it to the queue

31

 

return super.offer(o);

32

 

}

33

}

 

 

Tomcat自定义任务线程                                                                    

Tomcat中通过自定义任务线程TaskThread实现对每个线程创建时间的记录;使用静态内部类WrappingRunna- ble对Runnable进行包装,用于对StopPooledThreadException异常类型的处理。

 

/**
* A Thread implementation that records the time at which it was created.
*
*/
public class TaskThread extends Thread {
private final long creationTime;
public TaskThread(ThreadGroup group, Runnable target, String name) { super(group, new WrappingRunnable(target), name); this.creationTime = System.currentTimeMillis();
}
/**
*Wraps a {@link Runnable} to swallow any {@link StopPooledThreadException}
*instead of letting it go and potentially trigger a break in a debugger.
*/
private static class WrappingRunnable implements Runnable { private Runnable wrappedRunnable; WrappingRunnable(Runnable wrappedRunnable) {
this.wrappedRunnable = wrappedRunnable;
}
@Override   public void run() {
try {
wrappedRunnable.run();
} catch(StopPooledThreadException exc) {
//expected : we just swallow the exception to avoid disturbing
//debuggers like eclipse's
log.debug("Thread exiting on purpose", exc);
}
}
}
}

 

带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(7)https://developer.aliyun.com/article/1340062?groupCode=taobaotech

相关文章
|
8月前
|
存储 监控 Java
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
360 60
【Java并发】【线程池】带你从0-1入门线程池
|
6月前
|
Java
线程池是什么?线程池在实际工作中的应用
总的来说,线程池是一种有效的多线程处理方式,它可以提高系统的性能和稳定性。在实际工作中,我们需要根据任务的特性和系统的硬件能力来合理设置线程池的大小,以达到最佳的效果。
154 18
|
9月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
8月前
|
安全 Java C#
Unity多线程使用(线程池)
在C#中使用线程池需引用`System.Threading`。创建单个线程时,务必在Unity程序停止前关闭线程(如使用`Thread.Abort()`),否则可能导致崩溃。示例代码展示了如何创建和管理线程,确保在线程中执行任务并在主线程中处理结果。完整代码包括线程池队列、主线程检查及线程安全的操作队列管理,确保多线程操作的稳定性和安全性。
|
11月前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
249 38
|
11月前
|
Java
.如何根据 CPU 核心数设计线程池线程数量
IO 密集型:核心数*2 计算密集型: 核心数+1 为什么加 1?即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保 CPU 的时钟周期不会被浪费。
361 4
|
10月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
11月前
|
Java
线程池内部机制:线程的保活与回收策略
【10月更文挑战第24天】 线程池是现代并发编程中管理线程资源的一种高效机制。它不仅能够复用线程,减少创建和销毁线程的开销,还能有效控制并发线程的数量,提高系统资源的利用率。本文将深入探讨线程池中线程的保活和回收机制,帮助你更好地理解和使用线程池。
475 2
|
5月前
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
192 0
|
8月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
134 26