javaEE->多线程:线程池

线程池

线程诞生的意义:因为进程的创建/销毁,太重量了(比较慢)

但如果近一步提高创建/销毁的频率,线程的开销也不容忽视。

有两种方法可以提高效率:

1.协程(轻量级线程):相对于线程,把系统调度的过程省略了。

使用协程更多的是go和python

不知道协程能提升多少,防止出现bug,java一般使用线程

2.线程池:帮线程兜底,不至于很慢(就像现实生活中的"海王")

(内存池、线程池、进程池含义类似)

在使用第一个线程的时候,提前把2,3,4,5(其余)线程创建好;

后续如果想要使用新的线程,不必重新创建,直接调用即可,没有真正的频繁创建销毁,只是从线程池里面取线程使用,等使用完了在还给线程池,这样的话创建线程的开销就减少了。

调用线程比创建新线程效率更高

1.调用线程是纯粹"用户态"的操作

2.创建新的线程 是需要"用户态+内核态"共同完成的

内核态和用户态:

一段程序在系统内核执行 -> 内核态;

反之,用户态。

官方文档

在java标准库里面,ThreadPoolExecutor类表示线程池。

ThreadPoolExecutor类的构造方法

参数具体含义:

1. 线程数:int corePoolSize, int maximumPoolSize(核心线程数和最大线程数)

corePoolSize -> 核心线程数 -> 正式员工数

maximumPoolSize -> 最大线程数 -> 正式员工数 + 实习员工数

  • 线程池允许创建的最大线程数量。
  • 当工作队列满了,并且当前线程数小于最大线程数时,线程池会创建新的线程来处理任务

eg:

当核心线程处于忙碌中且有大量新的任务需要处理时,会创建实习员工线程,来帮核心线程处理;当任务数量变少时且持续一段时间,核心线程可以闲着(摸鱼),但实习员工线程全部销毁,提高了效率且节省了系统开销。

2. long keepAliveTime, TimeUnit unit(保持存活时间和存活时间的单位)

keepAliveTime:当线程池中的线程数量超过核心线程数时,多余的空闲线程在等待任务的时间超过这个值后,就会被销毁

unit:hour、min、s、ms

3.BlockingQueue<Runnable> workQueue

用来存放线程池中的任务的队列,使用Runnable来描述任务主体。

根据需要设置:

需要优先级:设置PriorityBlockingQueue

不需要优先级,并且任务数目相对恒定:使用ArrayBlockingQueue

不需要优先级,并且任务数目变动大:使用LinkedBlockingQueue

4.ThreadFactory threadFactory(线程工厂)

通过这个工厂类创建线程(Thread)对象,工厂类里面有方法封装了new Thread的操作,同时给Thread设置了一些属性,我们想要创建线程的时候可以直接使用工厂类的方法创建。

eg:

通过静态方法来封装new操作,在这个静态方法设置不同的属性,构造对象的过程,就称为工厂模式。

5.RejectedExecutionHandler handler(拒绝策略)

workQueue满了,并且线程池中的线程数量已经达到最大线程数时,新的任务将会被拒绝线程池会采用拒绝策略。

Executors类:工厂类

ThreadPoolExecutor使用较复杂,所以通过封装,创建了工厂类Executors;

通过这个类可以创建出不同的线程池对象,内部已经把ThreadPoolExecutor创建好并设置好参数。

eg;使用newFixedThreadPool(4)创建了固定线程数目为4的线程池,往里面添加任务。

线程池的执行流程

线程池如何设置线程数目

我们将任务分为CPU密集型和I/O密集型

**CPU密集型:**在cpu上执行,当线程数超过CPU核心数时,线程需要竞争CPU时间片,这会带来额外的开销,降低效率。

所以线程数目不应超过N(CPU核心数)

**I/O密集型:**涉及大量I/O操作,大部分都是在等I/O完成,不是执行CPU,(当一个线程在执行I/O操作时,它会阻塞,释放CPU。此时,CPU可以去执行其他线程的任务)。

I/O密集型任务的线程数可以设置得比CPU核心数多,超过N。

在实际应用中,任务往往是CPU密集型和I/O密集型的混合体。更好的方法是通过实验/测试的方法,找出合适的线程数目。

线程池的模拟实现

相关推荐
lifallen5 分钟前
Paimon vs. HBase:全链路开销对比
java·大数据·数据结构·数据库·算法·flink·hbase
m0_6948455714 分钟前
服务器如何配置防火墙规则开放/关闭端口?
linux·服务器·安全·云计算
降世神童23 分钟前
华为云Flexus+DeepSeek征文| 使用华为云CCE容器部署Dify-LLM高可用方案的验证与测试
运维·华为云·aigc
降世神童24 分钟前
华为云Flexus+DeepSeek征文| 基于华为云Dify-LLM高可用平台开发运维故障处理智能体
运维·华为云·aigc
深栈解码44 分钟前
JMM深度解析(三) volatile实现机制详解
java·后端
liujing102329291 小时前
Day04_刷题niuke20250703
java·开发语言·算法
阿巴~阿巴~1 小时前
Linux基本命令篇 —— alias命令
linux·服务器·bash
wjcurry1 小时前
多线程知识
多线程
Brookty1 小时前
【MySQL】JDBC编程
java·数据库·后端·学习·mysql·jdbc
能工智人小辰1 小时前
二刷 苍穹外卖day10(含bug修改)
java·开发语言