并发学习记录17:tomcat线程池
tomcat在哪里用到了线程池
- LimitLatch用来限流,可以控制最大连接个数
- acceptor负责接收新的socket连接
- poller负责监听socket channel是否有可读的IO事件
- 一旦有可读的IO事件被监听到,就封装一个任务对象socketProcessor,提交给executor线程池处理
- executor线程池中的工作线程最终负责处理请求
tomcat线程池扩展了ThreadPoolExecutor:
如果总线程达到了最大线程数,不会立刻抛出RejectedExecutionException异常,而是会再次尝试将任务放入队列,如果还是失败,才会抛出RejectedExecutionException异常。
tomcat-7.0.42部分源码
public void execute (Runnable command,long timeout, TimeUnit unit){
submittedCount.incrementAndGet();
try {
// 执行任务
super.execute(command);
// 出现异常
} catch (RejectedExecutionException rx) {
// 尝试将任务先放入队列,如果失败,才再次抛出异常
if (super.getQueue() instanceof TaskQueue) {
final TaskQueue queue = (TaskQueue) super.getQueue();
try {
if (!queue.force(command, timeout, unit)) {
submittedCount.decrementAndGet();
throw new RejectedExecutionException("Queue capacity is full.");
}
} catch (InterruptedException x) {
submittedCount.decrementAndGet();
Thread.interrupted();
throw new RejectedExecutionException(x);
}
} else {
submittedCount.decrementAndGet();
throw rx;
}
}
}
TaskQueue的force方法:将任务放入等待队列
public boolean force(Runnable o, long timeout, TimeUnit unit) throws InterruptedException {
if ( parent.isShutdown() )
throw new RejectedExecutionException(
"Executor not running, can't force a command into the queue"
);
return super.offer(o,timeout,unit); //forces the item onto the queue, to be used if the task
is rejected
}
tomcat添加新任务的流程
如果提交的任务数 < 核心线程数,那么任务直接被提交到任务队列等待执行
如果提交的任务数 >= 核心线程数,且提交的任务数 < 最大线程数,那么也加入任务队列等待运行
如果提交的任务数 >= 最大线程数, 那么就创建救急线程运行任务
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现