java 线程池详解

本文详细介绍了Java线程池的工作原理和核心参数,包括核心线程数、最大线程数、线程存活时间等,并讲解了线程池的创建、任务提交方式以及关闭策略。此外,还探讨了不同类型的阻塞队列和线程池的拒绝策略,如AbortPolicy、CallerRunsPolicy等,帮助读者深入理解线程池的管理和优化。
摘要由CSDN通过智能技术生成
今天学习下线程池的使用以及原理,还是对着java并发编程艺术这本书讲解的,线程池主要用于需要异步或并发执行任务的程序都可以使用线程池,为什么要使用线程池,而不是自己去创建线程呢?使用线程池三个优点:

1:将低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗,如果你不使用线程池,而是自己去创建线程,比如要100个线程你都要去创建的话,内存也吃不消,这就大大消耗了内存,既然你创建消耗了内存,所以你线程执行完销毁也是需要消耗内存的.

2:提高响应速度:当任务达到时,认为可以不需要等待线程创建就能立即执行

3:提高线程的可管理性:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,这是指消耗cpu,因为cpu要分配时间片给线程执行,还会降低系统的稳定性,线程多了,出错的概率就越大,并发本来就比较难把握.

当我们向线程池提交一个任务之后,线程池是如何处理这个任务呢?线程池处理线程的流程如下:

1:线程池判断核心线程池里的线程是否都在执行.如果不是,则创建一个新的工作线程来执行,如果核心线程池里的都在执行任务,则进入第二步:

2:线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里,如果工作队列满了,则进入第三步

3:判断线程池的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任务,如果已经满了,则交给饱和策略来处理这个任务.

现在画一个流程图对线程池的流程做个梳理:

在java中线程池用ThreadPoolExecutor类表示,要实例化这个对象呢?有二种方法,一种是直接new,一种是通过jdk给我们提供的工具类Executors,Executors是单例的

现在看下ThreadPoolExecutor类的构造函数:

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

参数说明:

1:corePoolSize:线程池中核心线程数,当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行任务也会创建线程,等到需要执行的任务大于线程池中的核心线程数,就不会再创建,如果调用了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程

2:maximumPoolSize:线程池最大线程数,也就是线程池允许创建的最多线程数,如果队列满了,并且已创建的线程数小于线程池设置的最多线程数,则线程池会再创建新的线程执行任务,注意,如果使用了无界的任务队列这个参数就不起什么作用.

3:keepAliveTime:(线程活动保持的时间)线程池的工作线程空闲后,保持存活的时间,如果任务很多,并且每个任务执行的时间比较短,可以调大时间,提高线程的利用率

4:unit(线程活动保持时间的单位):可选的单位有天DAYS,小时HOURS,分钟MINUTES,毫秒MILLISECONDS,微妙MICROSECONDS,千分之一毫秒和纳秒NANOSECONDS=千分之一微妙

5:workQueue(阻塞队列),用于保存等待执行任务的阻塞队列,jdk提高了好几种阻塞队列,这个会等下细讲6:threadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置一个更有意义的名字,一般很少使用.

7:handler(饱和策略),当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务,这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常,在jdk1.5中线程池框架提供了4种策略:AbortPolicy:直接抛出异常CallerRunsPolicy:只用调用者所在线程来执行任务DisCardOldestPolicy:遗弃队列里最近的一个任务,并执行当前任务.DiscardPolicy:不处理,直接遗弃,来自网上的一张图:


线程池执行二种方式

当我们创建好了线程池对象后,就可以向线程池提交任务,提交任务有种方式,分别有execute()和submit(),

execute()方法提交任务不需要返回值,所以无法判断任务是否被线程池执行成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值