• java线程池参数详解


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

    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两倍。

    2.如何来设置

    a.需要几个数据来计算

    tasks:每秒的任务数,假设为500~1000

    taskCost:每个任务需要花费的时间,假设为0.1s

    responseTime:系统允许的最大响应时间,假设为2s

    b.计算过程

    --corePoolSize=每秒需要的线程数?

    threadCount=tasks/(1/taskCost)=tasks*taskCost=(500~1000)*0.1=50~100个线程。corePoolSize的个数应该大于等于50。根据8020原则,如果每秒80%的时间执行200个任务,那么corePoolSize设置为80即可。

    --queueCapacity=(coreSizePool/taskCost)*responseTime

    计算可得queueCapacity=(80/0.1)*2。意思是队列里的线程可以等待2秒,超过了就需要开新的线程来执行,千万不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不会开新的线程来执行,响应时间也会陡增。

    --maxPoolSize=(max(tasks)-queueCapacity)/(1/taskCost)

    计算可能maxPoolSize=(1000-80)/10=92,(最大任务数-队列容量)/每个线程每秒处理的任务数=最大线程数

    --rejectedExecutionHandler:根据具体情况来决定,任务不重要可以丢弃,也可采用排队等策略

    --keepAliveTime和allowCoreThreadTimeout通常采用默认值就可以

    c.上面的计算都是理想的情况,在实际生产中,还要根据机器的性能,通横向扩展或者升级机器硬件来处理高并发产生的任务数

  • 相关阅读:
    LeetCode算法题-Sum of Two Integers(Java实现)
    LeetCode算法题-Valid Perfect Square(Java实现-四种解法)
    LeetCode算法题-Intersection of Two Arrays II(Java实现)
    LeetCode算法题-Intersection of Two Arrays(Java实现-四种解法)
    LeetCode算法题-Reverse Vowels of a String(Java实现-四种解法)
    LeetCode算法题-Reverse String(Java实现)
    LeetCode算法题-Power of Four(Java实现-六种解法)
    LeetCode算法题-Power Of Three(Java实现-七种解法)
    添加动态输出 Adding Dynamic Output 精通ASP-NET-MVC-5-弗瑞曼 Listing 2-7
    关于 退步编程 和 退步看书的思考
  • 原文地址:https://www.cnblogs.com/yy1234/p/14134292.html
Copyright © 2020-2023  润新知