线程池

本贴最后更新于 1625 天前,其中的信息可能已经沧海桑田

一、线程池的优点

  • 减少资源创建 => 减少内存开销,创建线程占用内存

  • 降低系统开销 => 创建线程需要时间,会延迟处理的请求

  • 提高稳定稳定性 => 避免无限创建线程引起的 OutOfMemoryError

二、线程池参数

  • 核心线程数 corePoolSize
  • 最大线程数 maxPoolSize
  • 缓冲队列 queueCapacity
  • 可空闲时间 keepAliveSeconds
  • 拒绝策略 rejectedExecutionHandler
  • 异步线程前缀 threadNamePrefix
  • 时间单位 unit

代码举例

 /**
     * 计算的线程池
     *
     * @return
     */
    @Bean("calculateExecutor")
    public Executor calculateExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        /** 核心线程数20:线程池创建时候初始化的线程数 **/
        executor.setCorePoolSize(20);
        /** 最大线程数200:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程 **/
        executor.setMaxPoolSize(50);
        /** 缓冲队列200:用来缓冲执行任务的队列 **/
        executor.setQueueCapacity(2000);
        /**允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁 **/
        executor.setKeepAliveSeconds(60);
        /**异步线程前缀**/
        executor.setThreadNamePrefix("calculateExecutor-");
        /**直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务**/
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
      
        return executor;
    }

三、线程池工作流程

线程工作流.jpg

  • 判断核心线程数是否已满,核心线程数大小和 corePoolSize 参数有关,未满则创建线程执行任务

  • 若核心线程池已满,判断队列是否满,队列是否满和 workQueue 参数有关,若未满则加入队列中

  • 若队列已满,判断线程池是否已满,线程池是否已满和 maximumPoolSize 参数有关,若未满创建线程执行任务

  • 若线程池已满,则采用拒绝策略处理无法执执行的任务,拒绝策略和 handler 参数有关

四、ExecutorService 中的四种线程池

  • 创建可缓存的线程池
ExecutorService executor=Executors.newCachedThreadPool (n)

如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

  • 创建单线程的线程池
ExecutorService executor=Executors.newSingleThreadExecutor()

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

  • 创建固定长度的线程池
ExecutorService executor=ecutors.newFixedThreadPool(n)
  • 创建定时线程池
ExecutorService executor=newScheduledThreadPool(n)

创建一个定长线程池,支持定时及周期性任务执行。

ExecutorService executor=newScheduledThreadPool(1);  
executor.scheduleAtFixedRate(() -> {  
 	try{  
 		...// 线程任务处理  
 	}catch (Exception e){  
 		e.printStackTrace();  
 	}  
 }, 0, 10, TimeUnit.SECONDS);

注意:

1、ScheduledExecutorService 遇到异常后续任务不继续执行,需要加 try cache 防止任务终止
2、定时线程分两种

  • scheduleAtFixedRate(commod,initialDelay,period,unit)
    系统启动后按照固定频率来执行
  • scheduleWithFixedDelay(commod,initialDelay,delay,unit)
    上一个任务执行完 delay 一定时间后开始执行下一个任务

五、线程池的拒绝策略

  • 直接丢弃(DiscardPolicy)
  • 丢弃队列中最老的任务(DiscardOldestPolicy)
  • 抛异常(AbortPolicy)
  • 将任务分给调用线程来执行(CallerRunsPolicy)

六、禁用 Executors 创建线程池

      亲自踩过坑,Executors 创建线程池中 FixedThreadPool 和 SingleThreadExecutor 允许的请求队列长度 Integer.MAX_VALUE,当任务太多时会在任务队列堆积大量的请求,从而引起 OOM 异常;CachedThreadPool 允许创建的线程数为 Integer.MAX_VALUE,当任务太多时会创建太多的线程数,从而引起 OOM 异常。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...