线程池
一、初始化线程的几种方式?
1、继承Thread
2、实现Runnable接口
3、实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)
4、创建线程池的方式。
方式1和方式2:主线程无法获取线程的运算结果。
方式3:主线程可以获取线程的运算结果,但是不利于控制服务器中的线程资源,可能导致服务器资源耗尽。
方式4:可以通过如下方式初始化线程池。
通过线程池初始化,性能稳定,也可以获取执行结果,并捕获异常。但是在业务复杂情况下,一个异步调用可能会依赖于另一个异步调用的执行结果。
Executors.newFixedThreadPool(10);
//或者
new ThreadPoolExecutor(
corePoolSize 5,
maximumPoolSize 200,
keepAliveTime 10,
TimeUnit TimeUnit.SECONDS,
BlockingQueue<Runnable> new LinkedBlockingQueue<>(10000),
ThreadFactory Executors.defaultThreadFactory(),
RejectedExecutionHandler new ThreadPoolExecutor.AbortPolicy()
);
二、线程池创建的七大参数
1.线程池各参数的含义
int corePoolSize:[5]核心线程数【5个一直存在除非设置了allowCoreThreadTimeOut】,线程池创建好以后就准备就绪的线程数量,就等待来接收异步任务去执行。
int maximumPoolSize:最大线程数量;控制资源并发的。
long keepAliveTime:存活时间,如果当前数量大于核心线程数量。线程空闲的时间大于存活时间,释放除核心线程外的超存活时间的空闲线程。
TimeUnit unit:时间单位。
BlockingQueue workQueue:阻塞队列,如果任务有很多,就会将目前多的任务放在队列里面。只要有空闲的线程,就会去队列中取出新的任务继续执行。
ThreadFactory threadFactory:线程的创建工厂,也可以自定义。
RejectedExecutionHandler handler:如果队列满了按照我们指定的拒绝策略拒绝执行任务。
2.线程的运行流程
1、线程池创建好,准备好core数量的核心线程,准备接收任务
1.1、core满了,就将再进来的任务放进阻塞队列中,空闲的core就会自己去阻塞队列获取任务执行
1.2、阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量
1.3、max满了就用RejectedExecutionHandler拒绝任务
1.4、max都执行完了,在指定的时间keepAliveTime以后,释放,max-core数量的线程
主要有4种拒绝策略:
1. AbortPolicy:直接丢弃任务,抛出异常,这是默认策略
2. CallerRunsPolicy:只用调用者所在的线程来处理任务
3. DiscardOldestPolicy:丢弃等待队列中最旧的任务,并执行当前任务
4. DiscardPolicy:直接丢弃任务,也不抛出异常
2、线程池运行例题
假如一个线程池,corePoolSize:7,maximumPoolSize:20,workQueue:50,有100个线程同时进来,怎么分配?
先用7个直接可以得到执行,接下来50个进入阻塞队列排队,再多开13个线程继续执行。现在70个线程已经分配,剩下30个线程使用设置好的拒绝策略。
————————————————
版权声明:本文为CSDN博主「枫叶绯红」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44324963/article/details/108375479
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY