线程池

作者: zhengxc | 来源:发表于2018-09-18 11:12 被阅读0次

new thread弊端

  • 线程的每次创建和销毁性能差

  • 线程缺乏管理,可能造成无限制的创建,造成宕机或OOM

线程池好处

  • 重用已经存在的线程

  • 提高系统资源利用率

ThreadPoolExecutor

构造参数

  • corePoolSize:核心线程数量
  • maximumPoolSize:最大线程数量
  • keepAliveTime:线程(超出核心线程数的线程)的最大空闲时间
  • unit:最大空闲时间单位
  • workQueue:阻塞队列,存储等待执行的任务 java队列
  • threadFactory:线程工厂,用于创建线程
  • rejectHandler:当任务队列满时,所执行的拒绝策略
  • Runnable 中的run函数,即封装线程所执行的任务
  • ThreadPoolExecutor默认使用AbortPolicy拒绝策略,直接抛出一个RejectedExecutionException异常 拒绝策略
corePoolSize、maximumPoolSize、workQueue三者关系
  1. 池中线程数小于corePoolSize,无论是否有空闲线程,都会新建线程去执行任务
  2. 池中活跃线程大于corePoolSize,新任务进入队列,等待空闲线程执行
  3. 队列满,池中线程数小于maximumPoolSize,对新任务新建线程去执行
  4. 队列满,池中线程等于maximumPoolSize,对新任务执行拒绝策略

线程池中的函数

  1. execute():提交任务交给线程池执行
  2. submit():提交任务,可以返回执行结果 execute+future
  3. shutdown():等待任务都执行完,关闭线程池
  4. shutdownNow():不等待任务执行完,关闭线程池
  5. getTaskCount():返回已安排执行的大致任务总数(任务和状态在计算中有可能改变)
  6. getCompletedTaskCount():返回已经完成的大致任务总数(任务和状态在计算中有可能改变)
  7. getPoolSize():线程池中的线程数量
  8. getActiveCount():正在执行任务的大致线程数量

使用Executors工具类创建的线程池

  • newCachedThreadPool()
/**
  *创建一个根据需要创建新线程的线程池,当线程可用时将重用以前创建的线程,适用于执行许多短期的异步        
  *任务,如果没有可用线程将创建新线程放到池子中,超过60s空闲时间将销毁线程,因此长时间空闲的线 
  *程池不会消耗资源
  *
  */
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
  • newFixedThreadPool(int nThreads)
/**
  *创建一个固定数量的线程池,使用无界队列,当线程都处于活跃状态时,任务将加入到无界队列里面等待
  *有可用的线程,无限增加,不会触发拒绝策略
  */
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
  • newScheduledThreadPool(int corePoolSize)
/**
  *创建一个线程池,可以给定的延迟后运行,或者定期执行。
  */
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
  • newSingleThreadExecutor()
/**
  *创建一个Executor,它使用一个在无界队列中运行的工作线程。 (但请注意,如果此单个线程由于在关闭  
  *之前执行期间的故障而终止,则在需要执行后续任务时将使用新的线程。)保证任务顺序执行,并且在任 
  *何给定的时间不会有多个任务处于活动状态。与 newFixedThreadPool(1)的区别是用 
  *DelegatedExecutorService包装起来,不让你配置线程池
 */
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

线程个数大小的设置

计算密集型

应用需要非常多的CPU计算资源,在多核CPU时代,我们要让每一个CPU核心都参与计算,将CPU的性能充分利用起来,这样才算是没有浪费服务器配置,如果在非常好的服务器配置上还运行着单线程程序那将是多么重大的浪费。对于计算密集型的应用,完全是靠CPU的核数来工作,所以为了让它的优势完全发挥出来,避免过多的线程上下文切换,比较理想方案是 线程数 = CPU核数+1,也可以设置成CPU核数 * 2

//线程数 = CPU核数+1,也可以设置成CPU核数*2
int poolSize = Runtime.getRuntime().availableProcessors() * 2;
IO密集型

我们现在做的开发大部分都是WEB应用,涉及到大量的网络传输,不仅如此,与数据库,与缓存间的交互也涉及到IO,一旦发生IO,线程就会处于等待状态,当IO结束,数据准备好后,线程才会继续执行。因此从这里可以发现,对于IO密集型的应用,我们可以多设置一些线程池中线程的数量,这样就能让在等待IO的这段时间内,线程可以去做其它事,提高并发处理效率。对于IO密集型应用套用公式
线程数 = CPU核心数/(1-阻塞系数) 这个阻塞系数一般为0.8~0.9之间,也可以取0.8或者0.9

int poolSize = Runtime.getRuntime().availableProcessors() * (1-0.9);

相关文章

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • java----线程池

    什么是线程池 为什么要使用线程池 线程池的处理逻辑 如何使用线程池 如何合理配置线程池的大小 结语 什么是线程池 ...

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • Spring Boot之ThreadPoolTaskExecut

    初始化线程池 corePoolSize 线程池维护线程的最少数量keepAliveSeconds 线程池维护线程...

  • 线程池

    1.线程池简介 1.1 线程池的概念 线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性...

  • 多线程juc线程池

    java_basic juc线程池 创建线程池 handler是线程池拒绝策略 排队策略 线程池状态 RUNNIN...

  • ThreadPoolExecutor线程池原理以及源码分析

    线程池流程: 线程池核心类:ThreadPoolExecutor:普通的线程池ScheduledThreadPoo...

  • 线程池

    线程池 [TOC] 线程池概述 什么是线程池 为什么使用线程池 线程池的优势第一:降低资源消耗。通过重复利用已创建...

  • java 线程池使用和详解

    线程池的使用 构造方法 corePoolSize:线程池维护线程的最少数量 maximumPoolSize:线程池...

  • 线程池

    JDK线程池 为什么要用线程池 线程池为什么这么设计 线程池原理 核心线程是否能被回收 如何回收空闲线程 Tomc...

网友评论

      本文标题:线程池

      本文链接:https://www.haomeiwen.com/subject/hckrnftx.html