> 文章列表 > Java多线程之线程池

Java多线程之线程池

Java多线程之线程池

文章目录

  • 1. 线程池的作用
  • 2. 使用线程池的好处
  • 3. 线程池的七个参数
  • 4. 线程池执行任务的流程
  • 5. Java 标准库中的线程池
    • 1)newFixedThreadPool
    • 2)newCachedThreadPool
    • 3)newScheduleThreadPool
    • 4)newSingleThreadExecutor
  • 6. 对比两种提交任务的方法

1. 线程池的作用

创建和销毁线程都需要消耗系统资源,线程池就是为了降低系统资源消耗而存在的

线程执行完任务之后不会被销毁,而是放入线程池中,下次使用就直接在线程池中取,减少了创建和销毁线程消耗的资源

2. 使用线程池的好处

  • 降低系统资源消耗,通过重复利用线程池中的线程来降低创建和销毁线程的消耗
  • 提高响应速度,当任务到达时,不再需要等待创建完线程再执行
  • 提高线程的可管理性,使用线程池可以统一对线程进行分配、调度和监控

3. 线程池的七个参数

  • corePoolSize:核心线程最大数量,核心线程一经创建就不会被销毁,除非线程池销毁
  • maximumPoolSize:线程池中最大线程数量,总线程数 = 核心线程数 + 非核心线程数
  • keepAliveTime:非核心线程的最大空闲时间,非核心线程在 keepAliveTime 时间后还没有执行任务,就会被销毁
  • unit:keepAliveTime 的时间单位,秒、分钟或者其他单位
  • workQueue:阻塞队列,有 ArrayBlockingQueue、LinkedBlockingQueue 等,用来存放线程任务
  • ThreadFactory:线程工厂,用来创建线程
  • RejectedExecutionHandler:拒绝策略,如果任务数量超过线程池最大负荷(),该怎么处理
    • AbortPolicy():丢弃当前线程任务,抛出异常
    • DiscardPolicy():丢弃当前线程任务,不抛异常
    • DiscardOldestPolicy():丢弃阻塞队列队首任务,不抛异常
    • CallerRunsPolicy():当前任务由调用者线程执行

4. 线程池执行任务的流程

请添加图片描述

5. Java 标准库中的线程池

Java 标准库中提供了 Executers 类来创建线程池,Executers 类创建线程池的方法有以下几种

1)newFixedThreadPool

创建一个固定线程数量的线程池,每提交一个任务就创建一个工作线程,工作线程数量达到指定的最大值,就将任务放入阻塞队列中

2)newCachedThreadPool

创建一个可缓存线程池,此类线程池中的所有线程只有 60 秒的最大空闲时间,线程空闲超过 60 秒就会被销毁,线程数量几乎没有限制

3)newScheduleThreadPool

创建一个定长的线程池,此线程池支持周期性的执行和延时执行某一个任务

使用 scheduleAtFixedRate() 或 scheduleWithFixedDelay() 即可实现周期性的任务执行

// 创建线程池
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);// 以下两种方法结果相同,延迟五秒开始执行,每隔两秒执行一次
scheduledExecutorService.scheduleAtFixedRate(thread2, 5, 2, TimeUnit.SECONDS);scheduledExecutorService.scheduleWithFixedDelay(thread2, 5, 2, TimeUnit.SECONDS);

4)newSingleThreadExecutor

创建一个单线程化的线程池,线程池中只有唯一一个线程来执行任务,保证所有线程按照指定顺序执行,如果这个线程异常结束了,就会创建另一个线程来替代他。

6. 对比两种提交任务的方法

向线程池提交任务一般使用 execute() 和 submit()

  • execute() 方法用于提交不需要返回值的任务,所以无法判断任务是否被执行成功
  • submit() 方法用于提交需要返回值的任务,线程池会返回一个 Future 类型的对象,通过这个对象可以判断任务是否执行成功,可以通过该对象的 get() 方法获取返回值。