Java线程池

一、什么是线程池

        线程池是一个线程管理的工具类,它允许重用现有的线程,而不是每次新建一个线程就执行一个任务

二、工作原理

  • 当任务提交到线程池后,线程池会判断当前运行的线程数量是否超过线程池的最大线程数量,如果没有超过,就直接使用运行的线程执行任务;
  • 如果运行的线程数量达到最大数量,则新的任务会被放入阻塞队列中等待;
  • 当运行的线程数量低于最大数量时,线程池会从阻塞队列中取出任务使用空闲线程执行。

三、解决的主要问题

  • 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度。当任务到来时,无需创建线程就可以立即执行任务。
  • 提供线程限流保护。通过线程池控制线程最大数量,避免因无限制创建线程导致的内存溢出。

 四、如何使用线程池

 1.使用Executors提供的静态方法来创建常见的线程池

ExecutorService pool = Executors.newFixedThreadPool(5);

也可以自定义线程池

ThreadPoolExecutor pool = new ThreadPoolExecutor(
   corePoolSize, 
   maximumPoolSize,
   keepAliveTime,
   TimeUnit.SECONDS,
   new LinkedBlockingQueue<Runnable>());

其中corePoolSize指的是核心池的大小

maximumPoolSize指最大线程数

keepAliveTime是超出核心池大小的线程的最大空闲时间

当线程池中的线程数大于核心线程池大小时,这时多出来的线程属于非核心线程。非核心线程如果处于空闲状态(没有被分配任务),线程池就会进行线程回收。keepAliveTime指的就是在非核心空闲线程能够存在的最大时间。

TimeUnit.seconds(days,hours,minutes) 这个就是keepAliveTime所存在时间的单位。

new LinkedBlockingQueue<Runnable>() 是为了缓冲任务,防止任务丢失。

 2.提交任务

使用线程池执行任务使用execute()或submit()方法:

pool.execute(()->{
    方法体
}); 
Future<?> future = pool.submit(()->{
    方法体
});

3.关闭线程池

 使用shutdown()方法关闭线程池,已提交的任务会继续执行,但不会接收新任务

pool.shutdown();

使用shutdownNow()方法可以取消正在执行的任务,并尝试停止所有线程

pool.shutdownNow();

使用awaitTermination()方法等待线程池的所有任务完成后再终止

pool.awaitTermination(60, TimeUnit.SECONDS);

五、线程池的生命周期

线程池的生命周期主要包括以下几个阶段:

1.初始化阶段:

        当调用ThreadPoolExecutor的构造方法创建线程池对象时,就进入了初始化阶段。

这时会根据传入的参数,如线程池大小、线程工厂等来进行一些初始化设置。

2.运行阶段:

        当向线程池中提交任务时,线程池进入运行阶段。这时线程池会根据当前任务数量和线程池设置,动态的添加或移除线程。

具体来说:如果当前线程数小于corePoolSize,直接创建新线程运行任务,当前线程数等于corePoolSize,则任务进入队列等待,队列已满且当前线程数小于maximumPoolSize,则创建新线程运行任务,当前线程数等于maximumPoolSize,则使用拒绝策略处理新任务

3.销毁阶段:

        当不再向线程池提交新任务,并且所有任务都执行完毕时,线程池进入销毁阶段。

这时线程池会根据设置进行优雅关闭

        等待所有任务完成

        终止当前线程并清理资源

        线程池对象资源被回收

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值