一文读懂线程池的工作原理、销毁以及创建方式

为什么使用线程池?

在java中,通过实现Runnable接口或者继承Thread类(Thread类的本质也是实现了Runnable接口)可以实现多线程,调用start()方法开启了多线程。
但是,如果频繁的手动去创建和销毁线程的话,会降低系统的运行效率。

通过使用线程池可以对线程实现复用,减少创建和销毁线程的次数,可以执行多个任务,大大降低系统资源消耗。

线程池的特点是,系统初始化会创建多个线程,放入线程池,需要使用的时候直接从线程池中取,不需要的时候就放回去,提高了工作效率。

线程池的工作原理:

1、线程池在初始化的同时,会自动创建一定数量的线程,存放起来;

2、当手动调用execute()和submit()方法的时候,会主动将任务提交到线程池;

3、线程池会判断核心线程数量是否已满,如果已满,则查看线程队列是否已满,否则创建线程执行任务;

4、将任务添加到线程队列,如果线程队列已满,则判断线程池是否已满,否则加入任务队列等待执行;

5、判断线程池最大线程数量是否已满,如果已满则拒绝执行任务,否则创建线程执行任务。
在这里插入图片描述
线程池销毁:

1、调用shutdown()方法,等到所有正在执行的任务全部执行完毕之后才会销毁;

2、调用shutdownNow()方法,则会试图停止所有正在执行的线程;

如何创建线程池?

java有预置线程池:newSingleThreadExecutor,newFixedThreadPool,newCacheedThreadPool,newScheduledThreadPool,newWorkStealingPool。如果不适合,还可以使用ThreadPoolExecutor创建自定义线程池。主要构造方法:

public ThreadPoolExecutor(int corePoolSize,
                            int maximumPoolSize,
                            long keepAliveTime,
                            TimeUnit unit,
                            BlockingQueue<Runnable> workQueue)
 
 public ThreadPoolExecutor(int corePoolSize,
                            int maximumPoolSize,
                            long keepAliveTime,
                           TimeUnit unit,
                           BlockingQueue<Runnable> workQueue,
                           ThreadFactory threadFactory,
                           RejectedExecutionHandler handler)

可以看到,线程池创建的好坏与前四个参数有关。

1、corePoolSize: 核心线程数。刚创建线程池,没有,即不会预先创建。当任务到来,且当前线程没有超过corePoolSize,就会创建一个新线程执行该任务,即使其他线程是空闲。不会因为空闲而被释放,keepAliveTime不适用。

2、maximumPoolSize:最大线程数。如上面情况,如果当前线程超过corePoolSize,先尝试排队,如果队列满了或者其他情况不能入队,那么它不会排队,而是检查线程数是否达到maximumPoolSize,如果没有,就创建线程,直到线程数达到maximumPoolSize。

3、keepAliveTime:空闲线程存活时间。当线程池的线程数大于corePoolSize,额外空闲线程的存活时间。如果到了时间,还没有新任务,就会释放线程。值为0,表示线程不会超时释放。

4、unit:keepAliveTime的时间单位。

5、BlockingQueue:阻塞队列。可以使用LinkedBlockingQueue(默认无界)、ArrayBlockingQueue、PriorityBlockingQueue(无界)、SynchronousQueue(没实际存储空间)。使用无界队列,需要注意,线程数最多达到corePoolSize,新任务来只能排队,maximumPoolSize没意义。SynchronousQueue只有正好有空闲线程,才会入队成功,否则总是创建新线程,直到达到maximumPoolSize。

6、handler:任务拒绝策略。有界队列,线程数达到maximumPoolSize,队列满了,触发任务拒绝策略。四种处理方式:AbortPolicy(默认,抛出异常),DiscardPolicy(忽略新任务,不抛异常),DiscardOldestPolicy(扔掉等待时间最长,自己排队),CallerRunsPolicy(任务提交者线程执行任务)
最佳自定义创建线程池,队列有界,maximumPoolSize有限,使用任务拒绝策略。如果队列无界,服务不了的任务总是会排队,消耗内存,甚至引发内存不足异常。如果队列有界但maximumPoolSize无线,可能会创建过多线程,占内存和CPU。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tuple_Margin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值