首页 > 编程语言 >Java_多线程:线程池

Java_多线程:线程池

时间:2024-07-05 09:58:39浏览次数:20  
标签:执行 Java corePoolSize 创建 池中 任务 线程 多线程

1、线程池优点:

  • 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。
  • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

2、常用的线程池

  • newSingleThreadExecutor:创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。
  • newFixedThreadPool:创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
    FixedThreadPool是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。
  • newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
    特点
    • 工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
    • 如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
    • 在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统OOM。
  • newScheduledThreadPool:创建一个定长的线程池,而且支持定时的以及周期性的任务执行,支持定时及周期性任务执行。

3、线程池七个核心参数

  • corePoolSize : 核心线程大小。线程池一直运行,核心线程就不会停止。
  • maximumPoolSize :线程池最大线程数量。非核心线程数量=maximumPoolSize-corePoolSize
  • keepAliveTime :非核心线程的心跳时间。如果非核心线程在keepAliveTime内没有运行任务,非
    核心线程会消亡。
  • workQueue :阻塞任务队列。ArrayBlockingQueue,LinkedBlockingQueue等,用来存放线程任
    务。
  • defaultHandler :饱和策略。ThreadPoolExecutor类中一共有4种饱和策略。通过实现RejectedExecutionHandler接口。
    • AbortPolicy : 线程任务丢弃报错。默认饱和策略。
    • DiscardPolicy : 线程任务直接丢弃不报错。
    • DiscardOldestPolicy : 将workQueue队首任务丢弃,将最新线程任务重新加入队列执行。
    • CallerRunsPolicy :线程池之外的线程直接调用run方法执行。
  • ThreadFactory :线程工厂。新建线程工厂。

4、线程池的执行流程

在这里插入图片描述

  1. 线程池执行execute/submit方法向线程池添加任务,当任务小于核心线程数corePoolSize,线程池中可以创建新的线程,即使线程池中仍有空闲线程。
  2. 当任务大于核心线程数corePoolSize,就向阻塞队列workQueue添加任务。
  3. 阻塞队列workQueue满了,并且最大线程池大小maximumPoolSize > 核心线程数corePoolSize时,新提交任务会创建新的线程执行任务。
  4. 当提交任务数超过最大线程池大小maximumPoolSize,就会执行饱和策略
  5. 当线程池中超过核心线程数corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程。
  6. 当设置allowCoreThreadTimeOut(true)时,线程池中核心线程数corePoolSize线程空闲时间达到keepAliveTime也将关闭

5、execute()方法和submit()方法的区别

  • execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功
    与否。
  • submit()方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个future对象可以判断任务是否执行成功,并且可以通过future的get()方法来获取返回值,get()方法会阻塞当前线程直到任务完成,而使用 get(long timeout,TimeUnit unit) 方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。

6、扩展

线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

标签:执行,Java,corePoolSize,创建,池中,任务,线程,多线程
From: https://blog.csdn.net/2401_83326044/article/details/140132330

相关文章

  • 基于Java+SpringBoot+Vue的学生宿舍管理系统的设计与开发(源码+lw+部署文档+讲解等)
    文章目录前言项目背景介绍技术栈后端框架SpringBoot前端框架Vue数据库MySQL(MyStructuredQueryLanguage)具体实现截图详细视频演示系统测试系统测试目的系统功能测试系统测试结论代码参考数据库参考源码获取前言......
  • 【Linux】多线程(互斥 && 同步)
    我们在上一节多线程提到没有任何保护措施的抢票是会造成数据不一致的问题的。那我们怎么办?答案就是进行加锁。目录加锁:认识锁和接口:初始化:加锁&&解锁:全局的方式:局部的方式:原理角度理解:实现角度理解:同步:加锁:认识锁和接口:初始化:这个就是我们互斥锁的类型。......
  • 什么是构造函数?Java 中构造函数的重载如何实现?
    构造函数,就像是建筑房屋时的奠基仪式,是Java类中一个特殊的方法,主要用于初始化新创建的对象。每当创建一个类的新实例时,构造函数就会自动调用,负责为这个新对象分配内存,并对其进行必要的设置,确保对象处于可用状态。它有着与类同名的特殊身份,没有返回类型,甚至连void也不需要声明......
  • 阿里云OSS存储--java
    在yml文件配置属性,使用@Value进行注入@ComponentpublicclassAliOSSUtils{//外部属性注入@Value("${aliyun.oss.endpoint}")Stringendpoint;//@Value("${aliyun.oss.accessKeyId}")@Value("${aliyun.oss.accessKeySecret}")......
  • 多线程笔记
    目录1.概念进程与线程的区别:多线程的概念 多线程优缺点​编辑创建多线程的几种方式1、继承Thread类2、实现Runnable接口3、实现Callable接口实现Runnable和Callable有什么区别:相同点:不同点:注意点:4、线程池实现多线程创建线程的方式的比较实现runnable和继承t......
  • Java----String类
    publicintlength()返回此字符串的长度。publicbooleanequals(Strings)比较两个字符串内容是否相同、区分大小写publicbooleanequalsIgnoreCase(StringanotherString)将此字符串与指定对象进行比较,忽略大小写。publiccharcharAt(intindex)返回指定索引......
  • python爬虫3-多进程多线程协程
    多进程和多线程frommultiprocessingimportProcessimportthreadingdefprocess_worker():foriinrange(200):print(f"Processworker{i}")defthread_worker():foriinrange(200):print(f"Threadworker{i}")if__......
  • Java 有什么工具可以快速将CSV 存入关系型数据库
    在Java中,有多种工具和库可以快速将CSV文件的数据导入到数据库中。以下是几种常用的方法和工具:1.使用OpenCSV和JDBCOpenCSV是一个非常流行的库,可以轻松读取和写入CSV文件。结合JDBC,可以将CSV文件的数据快速存储到数据库中。示例代码首先,添加OpenCSV库的依赖(假设使用Maven):<dep......
  • 以银行卡取钱的流程为例的状态模式的 java 的 demo
    好的,下面我们将用状态模式来实现一个模拟从银行卡取钱的流程。假设我们有以下几个状态:输入卡输入密码选择操作取款取卡我们通过状态模式来实现这些状态之间的切换。状态接口首先,我们定义一个状态接口ATMState://ATMState.javapublicinterfaceATMState{void......
  • JavaScript中的异步模式
    JavaScript中的异步模式JavaScript语言的执行环境是“单线程(singlethread)”,就是指一次只能完成一个任务。如果有多个任务,就必须排队,等前面一个任务完成,再执行后面一个任务,以此类推。这种模式的好处是实现起来比较简单,执行环境相对单纯,坏处是只要有一个任务耗时很长,后面的任务......