Java线程池关键参数及线程池类型选择
⼀次读懂Java线程池关键参数及线程池类型选择
⼀、java线程池关键参数
针对java语⾔,通过线程池源码来分析线程池,线程池源码,可以看到,线程池主要包括以下⼏个参数:
源码中对每个参数的解释如下:
针对每⼀个参数,意思就是说:
(1)corePoolSize:核⼼线程数,该参数说明了在线程池中保持核⼼线程的数量,由⾃⼰定义,刚创建线程池时,⾥⾯的核⼼线程数为0,随着任务的添加,达到核⼼线程数,执⾏完任务之后,线程池⾥⾯的核⼼线程数⼀直维持在设置的核⼼线程数。
如下所⽰:开始创建了⼀个核⼼线程数为2的线程池,我们打印⼀下线程池信息,可以看到,线程池⾥⾯的核⼼线程数为0.
接下来,我们向线程池⾥添加4个任务,注意我们设定的核⼼线程数为2,当所有任务都执⾏完之后,我们看线程池⾥⾯的线程数有多少。通过下图我们可以看到,线程池⾥⾯提交的4个任务已经完成,这时,线程池⾥⾯存活的线程数为2(核⼼线程数),并没有变为0。核⼼线程数⽤⼀句话概括:核⼼线程数由我们程序员指定,在启动线程池,并没有往⾥⾯添加任务时,池⼦⾥⾯的线程数量为0,当达到核⼼线程数时,⽆论是否向池⼦⾥提不提交任务,池⼦⾥⾄少会保持核⼼线程数数量。
(2)最⼤线程数(maximumPoolSize):该参数定义了⼀个线程池中最多能容纳多少个线程。当⼀个任务提交到线程池中时,如果线程数量达到了核⼼线程数,并且任务队列已满,不能再向任务队列中添加任务时,这时会检查任务是否达到了最⼤线程数,如果未达到,则创建新线程,执⾏任务,否则,执⾏拒绝策略。可以通过源码来看⼀下。如下:可以看出,当调⽤submit(Runnable task)⽅法,将任务提交到线程池中时,会调⽤execute()⽅法去执⾏任务,在该⽅法内,会进⾏核⼼线程数,任务队列的判断,最后决定是执⾏或者是拒绝。总结起来就是:最⼤线程数参数,是在已经达到
核⼼线程池参数,并且任务队列已经满的情况下,才去判断该参数。
(3)keepAliveTime:(最⼤线程数—核⼼线程数)线程存活时间,线程池中⼤于核⼼线程数的那部分线程,即线程数总数量减去核⼼线程数的那部分线程,在执⾏完任务之后,在线程池中存活的时间。
(4)workQueue:任务队列,⽤来做缓冲作⽤,当提交到线程池中的任务核⼼线程数量不够⽤时,所有的核⼼线程都在执⾏任务,会将任务存到任务队列中,等待核⼼线程来执⾏。该参数主要是在核⼼线程数都在执⾏任务时,才起作⽤的参数,主要⽤来缓存任务。总结⼀句话:该参数主要是在核⼼线程数都在执⾏任务时,⽤来缓存任务的队列。等待线程去执⾏。
以上就是java线程池主要参数,下⾯来介绍⼀下java中的⼏种线程池
⼆、java线程池类型及选择
通过查看源码,java中存在以下线程池:
1.public static ExecutorService newFixedThreadPool()
2.public static ExecutorService newWorkStealingPool()
3.public static ExecutorService newSingleThreadExecutor()
java线程池创建的四种
4.public static ExecutorService newCachedThreadPool()
如下图所⽰:
下⾯分别解释每⼀种线程池特点和使⽤场景:
1.public static ExecutorService newFixedThreadPool()
创建⼀个可重⽤固定线程数的线程池,以共享的⽆界队列⽅式来运⾏这些线程。在任意点,在⼤
多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,
则在有可⽤线程之前,附加任务将在队列中等待。如果在关闭前的执⾏期间由于失败⽽导致任何
线程终⽌,那么⼀个新线程将代替它执⾏后续的任务(如果需要)。在某个线程被显式地关闭之
前,池中的线程将⼀直存在。
2.public static ExecutorService newWorkStealingPool()
jdk1.8新引进的线程池,创建⼀个拥有多个任务队列(以便减少连接数)的线程池。由于能够合理的使⽤CPU进⾏对任务操作(并⾏操作),所以适合使⽤在很耗时的任务中。
3.public static ExecutorService newSingleThreadExecutor()
返回⼀个只有⼀个线程的线程池,这个线程池可以在线程死后(或发⽣异常时)重新启动⼀个线程来替代原来的线程继续执⾏下去!
4.public static ExecutorService newCachedThreadPool()
创建⼀个可根据需要创建新线程的线程池,但是在以前构造的线程可⽤时将重⽤它们。对于执⾏
很多短期异步任务的程序⽽⾔,这些线程池通常可提⾼程序性能。调⽤ execute 将重⽤以前构造
的线程(如果线程可⽤)。如果现有线程没有可⽤的,则创建⼀个新线程并添加到池中。终⽌并
从缓存中移除那些已有 60 秒钟未被使⽤的线程。因此,长时间保持空闲的线程池不会使⽤任何资
源。
创建⼀个线程池,它可安排在给定延迟后运⾏命令或者定期地执⾏。
各种线程池应⽤场景
1.CachedThreadPool:适合使⽤在任务量⼤但耗时少的任务。
2.FixedThreadPool:适合使⽤在任务量⽐较固定但耗时长的任务。
3.ScheduledThreadPool:适合使⽤在执⾏定时任务和具体固定周期的重复任务。
4.SingleThreadPool:适合使⽤在多个任务顺序执⾏的场景。
关于线程的其他问题:
⼀般任务设多少个线程的问题?
这个需要根据具体任务和机器性能来综合考虑,通过不断的性能测试,分析出最佳线程数量。⼀般来讲:
1.CPU密集型:cpu利⽤率较⾼,设置线程数量和cpu核⼼数⼀样即可。使cpu得到充分利⽤。
2.IO密集型:IO密集型,主要进⾏长时间的IO操作,cpu利⽤率不如cpu密集型⾼,⼀般设置线程数为CPU两倍。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。