线程池

一、初始化线程的几种方式?

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

posted @ 2023-04-04 20:05  huigui_mint  阅读(15)  评论(0编辑  收藏  举报