2024年java并发基础教学

java并发基础教学线程池 简介 标准库中的线程池 线程池的执行流程 Executors 实现一个简单的线程池 简介 池 是一个非常重要的概念 我们之前学的字符串常量池就是一种常量池 除了常量池 还有数据库连接池 线程池 进程池 内存池 池有两个作用 提前把要用的对象准备好 对象用完后也不要立即释放 而是先留着 以备下次使用 我们主要来分析 它是存放线程的池 会把要使用的线程

大家好,我是讯享网,很高兴认识大家。



线程池

  • 🍉简介
  • 🍉标准库中的线程池
  • 🍌线程池的执行流程
  • 🍉Executors
  • 🍉实现一个简单的线程池

🍉简介

“池”是一个非常重要的概念,我们之前学的字符串常量池就是一种常量池

java 线程池并发查询_开发语言

  1. 提前把要用的对象准备好
  2. 对象用完后也不要立即释放,而是先留着,以备下次使用

我们主要来分析 它是存放线程的池,会把要使用的线程,用完之后也不会立即释放,而是。这样就可以节省创建及销毁线程的开销


🍉标准库中的线程池

标准库提供了 这个类,它的构造方法有很多参数

java 线程池并发查询_java-ee_02

我们分别来解释一下每个参数的含义

  1. corePoolSize —— 核心线程数
    标准库提供的线程池,它所持有的线程数并非是一成不变的,而是会根据当前任务量,自适应调节线程个数。即如果任务非常多,那就会多搞几个线程;反之则会缩减线程数
    核心线程数就是一个线程池里最少有多少个线程
  2. maximumPoolSize —— 最大线程数
    顾名思义,就是最多能有多少个线程
  3. keepAliveTime —— 保持存活时间
    就是某个线程,它的如果超过这个时间阈值,那就会被销毁掉(或者说空闲状态下能存活多久)
  4. unit —— 保持存活时间的时间单位(h、min、s、ms……)
  5. workQueue —— 一个阻塞队列
    和定时器类似,线程池中也可以持有多个任务,所以用一个阻塞队列来存放任务,如果任务有优先级的话,可以用 PriorityBlockingQueue。Runnable 是用来描述任务的主体java并发基础教学
  6. threadFactory —— 线程工厂
    首先要解释一下什么是工厂模式
    工厂模式是一种常见的,通过专门的来创建指定的对象
    它本质上是给 Java 语法填坑的。这里的“坑”指的是,方法重载没办法在返回值相同的前提下,重载参数个数相同、类型一样的方法
    而有时候要重载的方法,它们参数列表中的参数个数和类型虽然一样,但是意思不一样

举个例子,现在有一个类 Point,要用它来表示平面直角坐标系中的点,在数学中有两种表达形式:常规的坐标和极坐标

这样写编译器会报错
我们可以把原先两个方法改成静态方法,直接在方法内部创建一个对象并初始化,然后再返回这个对象
这种把创建对象和初始化封装起来,在静态方法内部完成这些操作的过程,想得到对象,就调用这个方法,它就会“加工”出一个对象,这就是工厂模式。代码如下:

讯享网
  1. handler —— 拒绝策略
    这个参数是最重要的一个参数
    线程池中的阻塞队列能够容纳的元素是有上限的,如果往队列中添加任务时,任务队列已经满了,那线程池会怎么做呢?
    这就涉及到拒绝策略了

有四种策略
①:直接抛出异常。此时原先任务和新任务都不执行
②:新的任务由添加任务的线程去执行,就是“谁揽的活谁去干”。此时新任务就不由线程池执行了
③:丢弃最老的任务
④:丢弃最新的任务

🍌线程池的执行流程

  1. 当一个新任务交给线程池,如果此时线程池中有空闲的线程,就会直接执行
  2. 如果没有空闲的线程且当前线程池的线程数量小于corePoolSize,就会创建新的线程来执行任务,否则就会将该任务加入到阻塞队列中
  3. 如果阻塞队列满了,就会创建一个新线程,从阻塞队列头部取出一个任务来执行,并将新任务加入到阻塞队列末尾
  4. 如果当前线程池中线程的数量等于maximumPoolSize,就不会创建新线程,就会去执行拒绝策略

🍉Executors

由于 ThreadPoolExecutor 参数比较多,用起来比较复杂,所以标准库还提供了另一个版本 —— ,它是由 ThreadPoolExecutor 后得到的,通过 Executors 创建出来的线程池对象,它内部已经把 ThreadPoolExecutor 创建好了并设置了参数

java 线程池并发查询_线程池_03

Q:Executors 和 ThreadPoolExecutor 分别在什么时候使用?
A:如果没什么要求,只是简单使用一下,那就用 Executors;而如果想要高度定制化(diy),那就使用 ThreadPoolExecutor,参数都由自己设置,掌控权在我们手上,这样可以避免一些不可控因素


🍉实现一个简单的线程池

方便起见,我们写一个线程数目固定的线程池

构造方法指定创建多少个线程,并把这些线程创建好。然后要有一个阻塞队列,持有要执行的任务。还要提供一个方法 —— submit,它用来添加新任务

 

测试一下:

讯享网

结果如下:

java 线程池并发查询_java-ee_04

因为线程是随机调度的,所以任务序号是无序的

小讯
上一篇 2024-12-31 07:50
下一篇 2024-12-24 20:52

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/8430.html