java线程池

new Thread

new Thread的弊端:

  • 每次新建线程新建的对象性能差
  • 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,占用过多系统资源导致死机或oom
  • 功能少,如定时执行,定期执行,线程终端

由此,java提供了四种线程池,它的目的在于

  • 重用存在的线程,减少对象创建,消亡的开销,性能佳
  • 有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
  • 提供定时执行,定期执行,单线程,并发控制等功能。

java中创建线程池

Executors是java线程池的顶层封装类,我们只需根据需要调用Executors中相应的方法即可。

Executors里可分为四种线程池

newCachedThreadPool创建一个可缓存的线程池。
如果线程池大小超过处理任务需要的线程,那么就会回收部分空闲的线程;
当任务数增加时,此线程池又可以添加新线程来处理任务;
此线程池不会对线程池大小做限制,线程池最大值取决于jvm能够创建的大小。

newFixedThreadPool创建一个固定大小的线程池。
每提交一个任务就会新建一个线程,直到线程达到线程池的最大值;
线程池的大小一旦达到最大值就不会变,每个线程的存活时间是无限的,如果某个线程因为执行异常而结束,线程池会再补充一个;
如果线程池中的所有线程都处于繁忙状态,新任务申请线程时会进入堵塞队列。

newSingleThreadExector创建一个只有一个线程的线程池。
线程存活时间是无限的;
当该线程繁忙时,新任务申请线程会进入堵塞队列中。

newScheduledThreadPool创建一个固定大小的线程池。
线程池内线程存活时间无限制。
它主要用来在给定的延迟之后运行任务,或者定期执行任务。
例如定时轮询数据库中表的结构。

四种线程池是如何执行的?

这四种线程池实际调用的还是ThreadPoolExecutor的构造方法。
Executors实际上调用的是ThreadPoolExecutor的构造方法(newScheduledThreadPool调用的是ScheduleThreadPoolExecutor的构造),我们看一下ThreadPoolExecutor参数最多的构造

public ThreadPoolExecutor(int corePoolSize,//线程核心线程数。线程池长期维持的线程数,即使线程处于idle状态也不会回收
                              int maximumPoolSize,//线程允许的最大线程数
                              long keepAliveTime,//空闲线程存活时间。当前线程池总数大于核心线程数时,终止多余的空闲线程的时间
                              TimeUnit unit,//销毁时间。超过这个时间,多余的线程会被回收
                              BlockingQueue<Runnable> workQueue,//存储等待执行线程的工作队列
                              ThreadFactory threadFactory,//创建线程工厂,定制线程的创建过程
                              RejectedExecutionHandler handler) //拒绝策略。当工作队列、线程池全满时如何拒绝新任务

这里有一个拒绝策略,它是如何处理的呢?

拒绝策略

  • AbortPolicy简单粗暴,直接抛出拒绝异常,这也是默认的拒绝策略
  • CallerRunsPolicy如果线程池未关闭,则会在调用者线程中直接执行新任务,这会导致主线程提交线程性能变慢
  • DiscardPolicy表示不处理新任务,即丢弃
  • DiscardOldestPolicy抛弃最老的任务,从队列中取出最老的任务然后放入新的任务执行

提交线程

有两种方式submit()和execute()
execute没有返回值,如果不需要直到线程的结果就使用execute()
submit()返回一个Future对象,如果想知道线程结果就使用submit()提交,而且它能在主线程中通过Future的get方法捕获线程中的异常

线程池的关闭

shutdown()不再接受新的任务,之前提交的任务等执行结束再关闭线程池
shutdownNow()不再接受新的任务,试图停止池中的任务再关闭线程池,返回所有未处理线程列表

posted @   我的小鱼干嘞  阅读(165)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示