带你读《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

相关文章
|
25天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
103 38
|
23天前
|
Java
线程池内部机制:线程的保活与回收策略
【10月更文挑战第24天】 线程池是现代并发编程中管理线程资源的一种高效机制。它不仅能够复用线程,减少创建和销毁线程的开销,还能有效控制并发线程的数量,提高系统资源的利用率。本文将深入探讨线程池中线程的保活和回收机制,帮助你更好地理解和使用线程池。
48 2
|
25天前
|
Prometheus 监控 Cloud Native
JAVA线程池监控以及动态调整线程池
【10月更文挑战第22天】在 Java 中,线程池的监控和动态调整是非常重要的,它可以帮助我们更好地管理系统资源,提高应用的性能和稳定性。
63 4
|
25天前
|
Prometheus 监控 Cloud Native
在 Java 中,如何使用线程池监控以及动态调整线程池?
【10月更文挑战第22天】线程池的监控和动态调整是一项重要的任务,需要我们结合具体的应用场景和需求,选择合适的方法和策略,以确保线程池始终处于最优状态,提高系统的性能和稳定性。
101 2
|
1月前
|
Java 数据库连接 数据库
不同业务使用同一个线程池发生死锁的技术探讨
【10月更文挑战第6天】在并发编程中,线程池是一种常用的优化手段,用于管理和复用线程资源,减少线程的创建和销毁开销。然而,当多个不同业务场景共用同一个线程池时,可能会引发一系列并发问题,其中死锁就是最为严重的一种。本文将深入探讨不同业务使用同一个线程池发生死锁的原因、影响及解决方案,旨在帮助开发者避免此类陷阱,提升系统的稳定性和可靠性。
49 5
|
1月前
|
Dubbo Java 应用服务中间件
剖析Tomcat线程池与JDK线程池的区别和联系!
剖析Tomcat线程池与JDK线程池的区别和联系!
109 0
剖析Tomcat线程池与JDK线程池的区别和联系!
|
1月前
|
网络协议 安全 Java
难懂,误点!将多线程技术应用于Python的异步事件循环
难懂,误点!将多线程技术应用于Python的异步事件循环
64 0
|
1月前
|
设计模式 Java 物联网
【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解
【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解
58 0
|
1月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
45 1
C++ 多线程之初识多线程
|
28天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
19 3