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()

4.public static ExecutorService newCachedThreadPool()

5.newScheduledThreadPool()

如下图所示:

下面分别解释每一种线程池特点和使用场景:

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 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资
源。

5.newScheduledThreadPool()

    创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

各种线程池应用场景

1.CachedThreadPool:适合使用在任务量大但耗时少的任务。

2.FixedThreadPool:适合使用在任务量比较固定但耗时长的任务。

3.ScheduledThreadPool:适合使用在执行定时任务和具体固定周期的重复任务。

4.SingleThreadPool:适合使用在多个任务顺序执行的场景。

5.newWorkStealingPool:适合使用在很耗时的任务中

关于线程的其他问题:

一般任务设多少个线程的问题?

这个需要根据具体任务和机器性能来综合考虑,通过不断的性能测试,分析出最佳线程数量。一般来讲:

1.CPU密集型:cpu利用率较高,设置线程数量和cpu核心数一样即可。使cpu得到充分利用。

2.IO密集型:IO密集型,主要进行长时间的IO操作,cpu利用率不如cpu密集型高,一般设置线程数为CPU两倍。

  • 9
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java线程池的实现原理主要涉及以下几个关键组件: 1. 任务队列(Task Queue):用于存储待执行的任务。线程池中的线程从任务队列中获取任务并执行。 2. 线程池管理器(ThreadPool Manager):负责创建、管理和销毁线程池。它会根据配置的参数(如线程池大小、最大线程数、线程空闲时间等)来控制线程池的行为。 3. 线程池(Thread Pool):由一组复用的线程组成。线程池中的线程可以重复使用,避免了频繁创建和销毁线程的开销。 4. 工作线程(Worker Thread):线程池中的每个线程都是一个工作线程,负责执行从任务队列中获取的任务。 线程池的实现原理如下: 1. 初始化线程池线程池管理器根据配置参数初始化一定数量的工作线程,并将它们加入线程池中。 2. 提交任务:当有任务需要执行时,将任务提交给线程池管理器。 3. 任务队列管理:线程池管理器将任务添加到任务队列中。 4. 工作线程执行任务:空闲的工作线程从任务队列中获取任务,并执行任务。 5. 监控线程状态:线程池管理器会监控工作线程的状态,如空闲时间、线程池大小等。 6. 线程回收:当线程池中的线程空闲时间超过设定的阈值时,线程池管理器可能会销毁一些空闲的线程,以减少资源占用。 Java线程池的实现原理可以优化多线程的管理和资源利用,避免了频繁创建和销毁线程的开销,提高了系统的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值