精华内容
下载资源
问答
  • Java线程池七个参数详解

    万次阅读 多人点赞 2019-04-23 11:14:33
    java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释。 从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、...

    java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释。

    从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。下面会对这7个参数一一解释。

    一、corePoolSize 线程池核心线程大小

    线程池中会维护一个最小的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除非设置了allowCoreThreadTimeOut。这里的最小线程数量即是corePoolSize。

    二、maximumPoolSize 线程池最大线程数量

    一个任务被提交到线程池以后,首先会找有没有空闲存活线程,如果有则直接将任务交给这个空闲线程来执行,如果没有则会缓存到工作队列(后面会介绍)中,如果工作队列满了,才会创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。线程池不会无限制的去创建新线程,它会有一个最大线程数量的限制,这个数量即由maximunPoolSize指定。

    三、keepAliveTime 空闲线程存活时间

    一个线程如果处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁,这里的指定时间由keepAliveTime来设定

    四、unit 空闲线程存活时间单位

    keepAliveTime的计量单位

    五、workQueue 工作队列

    新任务被提交后,会先进入到此工作队列中,任务调度时再从队列中取出任务。jdk中提供了四种工作队列:

    ①ArrayBlockingQueue

    基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

    ②LinkedBlockingQuene

    基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的。

    ③SynchronousQuene

    一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

    ④PriorityBlockingQueue

    具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

    六、threadFactory 线程工厂

    创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等

    七、handler 拒绝策略

    当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略:

    ①CallerRunsPolicy

    该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。

    ②AbortPolicy

    该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。

    ③DiscardPolicy

    该策略下,直接丢弃任务,什么都不做。

    ④DiscardOldestPolicy

    该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列

     

    到此,构造线程池时的七个参数,就全部介绍完毕了。

    个人独立博客:https://blog.it-follower.com/posts/1035400434.html

    展开全文
  • 一次读懂Java线程池关键参数及线程池类型选择 一、java线程池关键参数 针对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两倍。

    展开全文
  • java 线程池重要参数

    千次阅读 2018-10-12 12:49:43
    一、ThreadPoolExecutor的重要参数 1、corePoolSize:核心线程数 * 核心线程会一直存活,及时没有任务需要执行 * 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理 * 设置...

    一、ThreadPoolExecutor的重要参数

        1、corePoolSize:核心线程数
            * 核心线程会一直存活,及时没有任务需要执行
            * 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
            * 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
    
        2、queueCapacity:任务队列容量(阻塞队列)
            * 当核心线程数达到最大时,新任务会放在队列中排队等待执行
    
        3、maxPoolSize:最大线程数
            * 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
            * 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
    
        4、 keepAliveTime:线程空闲时间
            * 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
            * 如果allowCoreThreadTimeout=true,则会直到线程数量=0
    
        5、allowCoreThreadTimeout:允许核心线程超时
        6、rejectedExecutionHandler:任务拒绝处理器
            * 两种情况会拒绝处理任务:
                - 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
                - 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
            * 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
            * ThreadPoolExecutor类有几个内部实现类来处理这类情况:
                - AbortPolicy 丢弃任务,抛运行时异常
                - CallerRunsPolicy 执行任务
                - DiscardPolicy 忽视,什么都不会发生
                - DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
            * 实现RejectedExecutionHandler接口,可自定义处理器

    二、ThreadPoolExecutor执行顺序

            线程池按以下行为执行任务
        1. 当线程数小于核心线程数时,创建线程。
        2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
        3. 当线程数大于等于核心线程数,且任务队列已满
            - 若线程数小于最大线程数,创建线程
            - 若线程数等于最大线程数,抛出异常,拒绝任务

    三、如何设置参数

        1、默认值
            * corePoolSize=1
            * queueCapacity=Integer.MAX_VALUE
            * maxPoolSize=Integer.MAX_VALUE
            * keepAliveTime=60s
            * allowCoreThreadTimeout=false
            * rejectedExecutionHandler=AbortPolicy()
    
        2、如何来设置
            * 需要根据几个值来决定
                - tasks :每秒的任务数,假设为500~1000
                - taskcost:每个任务花费时间,假设为0.1s
                - responsetime:系统允许容忍的最大响应时间,假设为1s
            * 做几个计算
                - corePoolSize = 每秒需要多少个线程处理? 
                    * threadcount = tasks/(1/taskcost) =tasks*taskcout =  (500~1000)*0.1 = 50~100 个线程。corePoolSize设置应该大于50
                    * 根据8020原则,如果80%的每秒任务数小于800,那么corePoolSize设置为80即可
                - queueCapacity = (coreSizePool/taskcost)*responsetime
                    * 计算可得 queueCapacity = 80/0.1*1 = 80。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行
                    * 切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。
                - maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost)
                    * 计算可得 maxPoolSize = (1000-80)/10 = 92
                    * (最大任务数-队列容量)/每个线程每秒处理能力 = 最大线程数
                - rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理
                - keepAliveTime和allowCoreThreadTimeout采用默认通常能满足
    
        3、 以上都是理想值,实际情况下要根据机器性能来决定。如果在未达到最大线程数的情况机器cpu load已经满了,则需要通过升级硬件(呵呵)和优化代码,降低taskcost来处理。



    链接:http://www.imooc.com/article/5887

    展开全文
  • 曾看到过一篇写文章Java线程池实现原理及其在美团业务中的实践 ,有个问答是这样的 一开始传给线程池的最大值是 把运行时的线程池线程最大数量改掉了(从2改为了6)。 当然你可以结合其他技术写...

    曾看到过一篇写文章Java线程池实现原理及其在美团业务中的实践   ,有个问答是这样的

     

    一开始传给线程池的最大值是

    把运行时的线程池线程最大数量改掉了(从2改为了6)。

    当然你可以结合其他技术写自适应算法(不够则加,空闲多则减)。

    也当然有其他方式更改运行参数,不止线程池哦。

    担心很多后来码农没有读过以前的很多文献(不是短暂性流行框架),

    特别是sun公司。

    框架会过时,但理论很难过时,会进化,但底层能大改吗!!!

     

    参考:

    1. Java Management Extensions管理扩展原理解析 https://www.jb51.net/article/184218.htm

    2. 如何使用JMX来管理程序? https://www.cnblogs.com/ZhangZiSheng001/p/12128915.html

    3. 为什么应该设置 com.sun.management.jmxremote.rmi.port? https://www.jianshu.com/p/5884b5ecbe1a

    4. 【java】【eclipse】运行工程查看jmx信息 https://blog.csdn.net/meteoryuyu/article/details/83278236

    5.   电子书 O'Reilly - Java Management Extensions  https://github.com/dongguangming/java/blob/master/O'Reilly%20-%20Java%20Management%20Extensions.pdf

     

     

    展开全文
  • 关于Java线程池构造参数,你该了解这些!

    万次阅读 多人点赞 2019-10-24 19:19:02
    RejectedExecutionHandler handler) 构造函数一共有7个参数,如下: corePoolSize 线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为...
  • ThreadPoolExecutor的重要参数 1.corePoolSize:核心线程数 核心线程会一直存活,及时没有任务需要执行。 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理。 设置...
  • Java 线程池参数动态调节详解

    千次阅读 2020-04-16 09:46:28
    前言:曾经自诩对线程池了如指掌,不料看了美团的一篇技术文章后才知道原来线程池参数还可以动态调节。 经典面试题 在这篇文章中我主要回答上面抛出的这个问题:你这几个参数的值怎么来的呀? 要回答这个问题...
  • 详解Java线程池参数

    千次阅读 2019-02-16 12:18:55
    详解线程池参数 目前线程池的类一般使用 spring的:org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor JDK的:java.util.concurrent.ThreadPoolExecutor 它们的配置差不多,spring的做了...
  • 如何正确设置Java线程池参数

    千次阅读 2020-04-24 16:26:17
    如何正确设置Java线程池参数? 前言:在上篇文章我已经给读者介绍了Java线程池的基本使用,以及参数的定义。你真的了解Java线程池参数的含义吗 本文我们更进一步,来聊聊在实际的工作中如何设置Java线程池参数...
  • 线程池的核心参数 参数 类型 含义 corePoolSize int maximumPoolSize int keepAliveTime long unit TimeUnit workQueue BlockingQueue threadFactory ThreadFactory handler ...
  • 给女朋友讲 : Java线程池的内部原理

    万次阅读 多人点赞 2019-11-03 15:09:57
    餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”
  • 转载自:https://blog.csdn.net/it666dhw/article/details/78832066JDK1.5中引入了强大的concurrent包,其中最常用的莫过了线程池的实现ThreadPoolExecutor,它给我们带来了极大的方便,但同时,对于该线程池不恰当...
  • 为什么要使用线程池 在JavaSE中,要实现多线程的方式有多种,例如继承Thread、实现Runnable接口或者Callable接口。但是我们应该要知道,创建一个线程的开销是很大的,因为它总涉及与操作系统交互,我们知道,线程...
  • Java 线程池的各个参数的含义

    千次阅读 2020-06-25 05:59:26
    线程池参数2.线程池执行流程2.1 流程图2.2 线程创建的流程2.3 小结3.核心线程数和最大线程数4.keepAliveTime+时间单位5.ThreadFactory6.workQueue7.Handler8.参考 1.线程池参数 参数名 含义 corePoolSize ...
  • Java线程池参数解析

    千次阅读 2018-11-20 15:36:11
    核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者...
  • java线程池创建各个参数的作用 线程池可以通过ThreadPoolExecutor来创建,我们来看一下它的构造函数: JAVA线程池执行流程,即对应execute()方法: 提交一个任务,线程池里存活的核心线程数小于线程...
  • Java线程池参数分析

    千次阅读 2019-01-30 15:55:49
    实际上Executors创建的线程池实例最终都是通过实例化配置不同参数的ThreadPoolExecutor对象。 public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolEx...
  • java线程池参数详解

    2019-08-19 14:47:59
    一、线程池的三种创建方式(采坑点...二、线程池有以下七个参数,且线程池的底层的是ThreadPoolExecutor 对照上图的七个参数 三、线程池的底层工作原理 四、几个注意点 线程池的四种拒绝策略 ...
  • Java线程池参数配置

    2020-05-13 16:40:38
    线程池的实际使用中,参数的配置总让人难以把握。在网上搜了一下,主要有以下的方案。跟大家分享。 1. 基本概念 1.1 ThreadPoolExecutor的重要参数 corePoolSize:核心线程数 核心线程会一直存活,及时没有...
  • 拒绝策略RejectedExecutionHandler做一下详细的工作:在使用线程池并且使用有界队列的时候,如果队列满了,任务添加到线程池的时候就会有问题,针对这些问题java线程池提供了以下几种策略: (1)AbortPolicy (2)...
  • java线程池参数含义

    千次阅读 2017-04-14 16:54:12
    参数及设置 http://m.blog.csdn.net/article/details?id=7392607 项目中开发通常不会直接使用ThreadPoolExecutor,而是通过Executors.newFixedThreadPool()这种简易写法,创建适合自己项目的线程池。但是了解最...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 129,814
精华内容 51,925
关键字:

java线程池怎么转参数

java 订阅