当前位置: 首页 > news >正文

Java线程池和执行流程

在 Java 中,常见的四种线程池包括:

1. newFixedThreadPool(固定大小线程池)

  • 应用场景:适用于需要限制线程数量,并且任务执行时间比较均匀的场景,例如服务器端的连接处理。
  • 优点:线程数量固定,能够有效地控制并发线程数,避免过多的线程竞争资源。
  • 缺点:如果线程在执行任务过程中出现异常导致线程终止,而新任务被提交到线程池时,可能会出现等待,直到有线程被释放。
ExecutorService executor = Executors.newFixedThreadPool(5);

示例(下面的newCachedThreadPool、newSingleThreadExecutor的使用是类似的):

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class FixedThreadPoolExample {public static void main(String[] args) {// 创建一个固定大小为 5 的线程池ExecutorService executor = Executors.newFixedThreadPool(5);// 提交 10 个任务到线程池for (int i = 1; i <= 10; i++) {executor.execute(new Task(i));}// 关闭线程池,不再接受新任务,但会等待已提交任务完成executor.shutdown();}static class Task implements Runnable {private int taskNumber;public Task(int taskNumber) {this.taskNumber = taskNumber;}@Overridepublic void run() {System.out.println("Task " + taskNumber + " is running on thread: " + Thread.currentThread().getName());try {// 模拟任务执行耗时Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task " + taskNumber + " is completed");}}
}

2. newCachedThreadPool(可缓存线程池)

  • 应用场景:适用于执行很多短期异步任务的场景,例如网页服务器中的请求处理。
  • 优点:可以根据需要创建新线程,如果有可用的线程则复用,能灵活应对短时间内大量的任务请求。
  • 缺点:因为线程数量不固定,可能会创建大量线程,从而导致系统资源消耗过多。
ExecutorService executor = Executors.newCachedThreadPool();

3. newSingleThreadExecutor(单线程池)

  • 应用场景:适用于需要按顺序依次执行任务的场景,例如日志记录。
  • 优点:保证任务按顺序执行,避免多线程环境下的并发问题。
  • 缺点:执行效率相对较低,不适合并发量大的任务。
ExecutorService executor = Executors.newSingleThreadExecutor();

4. newScheduledThreadPool(定时任务线程池)

  • 应用场景:适用于需要执行定时任务或者周期性任务的场景,例如定时数据备份。
  • 优点:能够准确地按照设定的时间间隔执行任务。
  • 缺点:相对复杂,配置不当可能导致任务执行不准确。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);

示例:

package com.yuanmomo.demo.thread;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class ScheduledThreadPoolExample {public static void main(String[] args) {// 创建一个大小为 5 的定时任务线程池ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);// 延迟 3 秒后执行一次任务executor.schedule(new Runnable() {@Overridepublic void run() {System.out.println("延迟任务在3秒后执行");}}, 3, TimeUnit.SECONDS);// 每隔 2 秒执行一次任务executor.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println("执行周期任务");}}, 0, 2, TimeUnit.SECONDS);// 运行一段时间后关闭线程池try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}executor.shutdown();}
}

线程池执行流程

在这里插入图片描述

  1. 任务提交
    • 当向线程池提交一个任务时,线程池会首先判断当前运行的线程数量是否小于核心线程数量。
    • 如果小于,会创建一个新的线程来执行任务。
  2. 核心线程池已满
    • 若核心线程数量已达到设定的最大值,新提交的任务会被放入任务队列中等待执行。
  3. 任务队列已满
    • 如果任务队列已满,并且当前运行的线程数量小于最大线程数,线程池会创建新的线程来执行任务。
  4. 达到最大线程数
    • 当线程数量达到最大线程数,并且任务队列已满时,新提交的任务会根据拒绝策略进行处理。
  5. 线程回收
    • 当线程空闲时间超过一定限度(可设置),且当前运行线程数大于核心线程数时,多余的空闲线程会被回收。

例如:
假设线程池的核心线程数为 5,最大线程数为 10,任务队列容量为 100,拒绝策略为抛出异常。

开始时,陆续提交 5 个任务,线程池会创建 5 个核心线程来执行这些任务。

接着继续提交任务,只要任务数未超过 100,新任务会被放入任务队列等待执行。

当任务队列已满,继续提交任务,此时会创建新的线程(最多到 10 个)来执行任务。

若线程数达到 10 且任务队列已满,再提交新任务,就会根据拒绝策略抛出异常。

线程来执行这些任务。

接着继续提交任务,只要任务数未超过 100,新任务会被放入任务队列等待执行。

当任务队列已满,继续提交任务,此时会创建新的线程(最多到 10 个)来执行任务。

若线程数达到 10 且任务队列已满,再提交新任务,就会根据拒绝策略抛出异常。

http://www.lryc.cn/news/421382.html

相关文章:

  • 进程信号的产生与处理
  • 统一响应结果封装,Result类的实现【后端 06】
  • 明日周刊-第20期
  • 深入剖析 Spring 常用注解:功能与差异的全景洞察
  • 【隐私计算篇】隐私计算使用不当也会泄露原始数据
  • C++第一讲:开篇
  • OceanBase V4.2特性解析:MySQL模式下GIS空间表达式的场景及能力解析
  • HSL模型和HSB模型,和懒人配色的Color Hunt
  • 什么是云原生?(二)
  • pytorch 47 模型剪枝实战|基于torch-pruning库代码对yolov10n模型进行剪枝
  • LeetCode_sql_day15(262.行程与用户)
  • 【MySQL】详解数据库约束、聚合查询和联合查询
  • bug积累
  • 版本控制案例:全球虚拟制片领导者Dimension借助Perforce Helix Core简化多供应商协作,控制访问权限,确保数据资产安全(下)
  • Anaconda配置envs和pcks路径
  • 推荐10个在线搭建框架平台
  • Linux Shell--函数
  • 漏洞复现-CVE-2023-42442:JumpServer未授权访问漏洞
  • 【数据结构之带头双向循环链表的实现】
  • 【docker】docker数据卷与网络部署服务
  • Spring MVC框架学习笔记
  • LeetCode 100道题目和答案(面试必备)(一)
  • OpenGL投影矩阵
  • Linux中的`make`与`Makefile`:项目自动化构建工具
  • GitHub开源项目精选:轻量级预约/预订日历组件,用React和TypeScript构建
  • 闲钱放在哪里?收益稳定且又高!
  • 【Linux】简易线程池项目
  • 基于vue框架的NBA球星管理系统1878g(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 【docker】Dockerfile练习
  • 数据可视化的魔法:Python Matplotlib库的奇妙之旅