java-线程池

news/2024/9/23 5:20:49/

1、线程池的自我介绍:
● 线程的数量过多会反复的创建并销毁
● 为什么使用线程池?
○ 第一:反复创建线程开销大
○ 第二:过多的线程会占用太多内存
解决以上两个问题的思路:
○ 用少量的线程-避免内存占用过多
○ 让这部分线程都保持工作,且可以反复执行任务—避免生命周期的损耗

2、线程池的参数
corePoolSize 核心线程数
maxPoolSize 最大线程数
keepAliveTime 保持存活时间(非核心线程的存活时间)
workQueue 任务存储队列
threadFactory ThreadFactory 当线程池需要新的线程的时候,会使用threadFactory来生成新的线程
Handler RejectedExecutionHandler 由于线程池无法接受你所提交的任务的拒绝策略
TimeUnit unit: keepAliveTime的时间单位

corePoolSize指的是核心线程数:线程池在完成初始化后,默认情况下,线程池中并没有任何线程,线程池会等待有任务到来时,再创建新线程去执行任务
线程池有可能会再核心线程数的基础上,额外增加一些线程,但是这些新增加的线程数有一个上限,这就是最大量maxPoolSize

3、添加线程的规则

  • 如果线程数小于核心线程数(corePoolSize),即使其他工作线程处于空闲状态,也会创建一个新线程来运行新任务
  • 如果线程数等于(或大于)核心线程数(corePoolSize)但少于最大线程数(maximumPoolSize),则将任务放入队列
  • 如果队列已满,并且线程数小于最大线程数(maxPoolSize),则创建一个新线程来运行任务
  • 如果队列已满,并且线程数大于或等于最大线程数(maxPoolSize)中,则拒绝该任务
    在这里插入图片描述

4、工作队列

  • 无界队列:LinkedBlockingQueue
    是一个单向链表实现的阻塞队列,先进先出的顺序,支持多线程并发操作,可以认为是无界队列
    新元素插入到队列的尾部,并且队列获取操作会获得位于队列头部的元素

  • 有界队列:ArrayBlockingQueue
    一个由数组支持的有界队列,此队列按先进先出原则对元素进行排序
    新元素插入到队列的尾部,队列获取操作则是从队列头部开始获取元素
    这是一个简单的“有界缓存区”,一旦创建,就不能在增加其容量

  • 同步队列:SynchronousQueue
    一个没有内部容量的同步队列,(容量为0,无论何时,size方法总是返回0)
    每个插入操作必须等待另一个线程进行相应的删除操作,反之亦然
    put操作阻塞,直到另外一个线程取走队列的元素
    take操作阻塞,直到另外的线程put某个元素到队列中
    任何线程只能取得其他线程put进去的元素,而不会取到自己put进去的元素

5、JDK提供的线程池

  • newFixedThreadPool (固定大小的线程池,核心线程池数量和最大线程池数量相等且可以手动设置数量)
public static ExecutorService newFixedThreadPool(int nThreads){return new ThreadPoolExecutor(nThreads,nThreads,keepAliveTime:0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())
}public static ExecutorService newFixedThreadPool(int nThreads,ThreadFactory threadFactory){return new ThreadPoolExecutor(nThreads,nThreads,keepAliveTime:0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory);
}

使用无界队列(LinkedBlockingQueue),容量没有上限,所以当请求数量越来越多,并且无法及时处理完毕的时候,也就是请求堆积的时候,会容易造成占用大量的内存,可能会导致OOM

  • newSingleThreadExecutor(单一线程池,核心线程池数量和最大线程池数量都为1)
public static ExecutorService newSingleThreadExecutor(){return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(corePoolSize:1,maximunPoolSize:1,keepAliveTime:0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()))
}public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory){return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(corePoolSize:1,maximunPoolSize:1,keepAliveTime:0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory))
}
  • CachedThreadPool (核心线程数量为0,最大线程数量为Integer类型的最大值,使用同步队列)
public static  ExecutorService newCachedThreadPool(){return new ThreadPoolExecutor(corePoolSize:0,Integer.MAX_VALUE,keepAliveTime:60L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>())
}public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory){return new ThreadPoolExecutor(corePoolSize:0,Integer.MAX_VALUE,keepAliveTime:60L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>(),threadFactory);
}
  • newScheduledThreadPool (核心线程数根据构造函数指定,最大线程数为Integer.MAX_VLAUE)
    ScheduledThreadPool是一个能实现定时、周期性任务的线程池。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);}public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());}public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) {return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);}public ScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue(), threadFactory);}

6、停止线程池的方法
shutdown:当执行完此方法后,不会立即停止线程,而是执行完已经创建好的线程再停止线程,如果再有新的线程加入,则会实行拒绝策略。

package ThreadPool;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** @author yjx* @description* @date*/
public class Shutdown {public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {ShutDown1 shutDown1 = new ShutDown1();System.out.println(shutDown1);executorService.execute(shutDown1);}Thread.sleep(1500);executorService.shutdown();executorService.execute(new ShutDown1());}
}class ShutDown1 implements Runnable{@Overridepublic void run() {try {Thread.sleep(500);System.out.println(Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();}}
}pool-1-thread-1
pool-1-thread-10
pool-1-thread-9
pool-1-thread-7
pool-1-thread-8
pool-1-thread-6
pool-1-thread-5
pool-1-thread-4
pool-1-thread-3
pool-1-thread-2Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task ThreadPool.ShutDown1@6f94fa3e rejected from java.util.concurrent.ThreadPoolExecutor@5e481248[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 10]at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)at ThreadPool.Shutdown.main(Shutdown.java:21)

isShutdown:判断是否进入停止状态
在这里插入图片描述
isTerminated:判断所有的任务是否已经执行完,当所有的任务已经执行完后返回true,否则返回false


http://www.ppmy.cn/news/5209.html

相关文章

嵌入式Linux驱动开发之点灯

使用驱动开发的方式点亮一个LED灯。看看两者有啥区别不&#xff1f; 一、先看原理图 首先查看原理图&#xff0c;看看我们的板子上的LED等接在哪一个IO口上面。 好了&#xff0c;看原理图我们知道LED灯接在芯片的GPIO1的第三个引脚上面&#xff0c;也就是GPIO1_IO03。 二、I…

前端基础(十三)_定位position、定位层级z-index

一、定位position Css的定位机制&#xff1a;普通文档流、浮动、定位 这里主要介绍CSS的定位属性&#xff1a;position&#xff1a; 1、定位原理&#xff1a;允许元素相对于正常位置、或者相对于父元素、浏览器窗口本上的位置 2、元素位置的调整&#xff1a; left|right属性、…

IDEASpring3:jdbcTemplate

1.jdbcTemplate Spring中的数据库操作模板&#xff0c;可以整合其它框架&#xff0c;如mybatis &#xff08;1&#xff09;对JDBC进行封装&#xff0c;使用jdbcTemplate可方便对数据库进行增删改查 2.准备工作 &#xff08;1&#xff09;引入依赖 mysql依赖、druid连接池、spri…

Python 帮同事用pandas快速筛选Excel文件

同事正在为怎样处理一个18万行的全年财务Excel文件发愁&#xff0c;文件足足有30M&#xff0c;打开文件也要两三分钟&#xff0c;于是他就向我求助。大概意思就是要筛选出Data工作簿“源数据”Sheet中所有收款人对应的付款人及付款笔数、金额小计&#xff0c;于是我简化做了一个…

ffmpeg-AVPacket

目录 引子 翻译一下官方注释&#xff1a; 成员变量&#xff1a; AVBufferRef *buf pts dts data size stream_index flag side_data side_data_elems duration pos opaque opaque_ref time_base 引子 AVPacket是ffmpeg基础且非常重要的数据结构…

Android实现红绿灯检测(含Android源码 可实时运行)

Android实现红绿灯检测(含Android源码 可实时运行) 目录 Android实现红绿灯检测(含Android源码 可实时运行) 1. 前言 2. 红绿灯检测数据集说明 3. 基于YOLOv5的红绿灯检测模型训练 4.红绿灯检测模型Android部署 &#xff08;1&#xff09; 将Pytorch模型转换ONNX模型 &…

可解释机器学习笔记合集

​task01 导论 【学习打卡01】可解释机器学习之导论Task01 预备知识学习 ​task02 ZFNet 【学习打卡】ZFNet深度学习图像分类算法【学习打卡02】可解释机器学习笔记之ZFNet【算法】可解释机器学习-ZFNet&#xff08;Datawhale)Task02 【算法】ZFNet ​task03 CAM 【学习打…

Nginx-反向代理

什么是反向代理 用户直接访问反向代理服务器就可以获得目标服务器的资源。这一过程叫反向代理 如何配置反向代理 修改nginx配置文件 1.切换到nginx的conf路径下操作nginx的配置文件 cd /usr/local/openresty/nginx/conf 1.1防止修改错误可以先备份一下配置文件 cp nginx.…