您当前的位置: 首页 > 

顧棟

暂无认证

  • 1浏览

    0关注

    227博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【JUC系列】线程池基础使用

顧棟 发布时间:2022-06-10 06:00:00 ,浏览量:1

线程池基础使用

文章目录
  • 线程池基础使用
    • 一、核心组件和核心类
    • 二、线程池的工作流程
    • 三、线程池的拒绝策略
    • 四、6种常用的线程池
    • 五、线程池的使用
      • 线程池的创建
      • 向线程池提交任务
      • 关闭线程池
      • ThreadPoolExecutorDemo示例
    • 六、线程池的好处

一、核心组件和核心类

4个核心组件

  • 线程池管理器 用于创建和管理线程
  • 工作线程 线程池中执行具体任务的线程
  • 任务接口 用户定义工作线程的调度和执行策略,只有线程实现了该接口,线程的任务才能够被线程池调度。
  • 任务队列 存放待处理的任务,新的任务加入队列,执行完成的任务会被队列移除。

java中的线程池通过Executor框架实现的核心类如下:

Executor、Executors 、ExecutorService、ThreadPoolExcutor、Callable、Future、 FutureTask

创建线程池的核心类ThreadPoolExcutor的核心方法

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        ...
    }

参数说明

  • corePoolSize:线程池中的核心线程数量

  • maximumPoolSize:线程池中最大线程数量

  • keepAliveTime:当线程数超过corePoolSize时,线程空闲存活时长

  • unit:的时间单位

  • workQueue:任务队列,被提交但是尚未执行的任务的存放处

  • threadFactory:线程工厂,用户创建线程,一般默认

  • handler:拒绝策略,任务过多或者其他原因导致线程池无法处理任务的拒绝策略。

二、线程池的工作流程

在这里插入图片描述

核心线程池和非核心线程池

核心线程不会被销毁 而非核心线在空闲后超过keepaliveTime之后会被销毁。

三、线程池的拒绝策略

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略。JDK内置的拒绝策略有4种。

ThreadPoolExecutor.AbortPolicy //默认,丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy //丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy //尝试丢弃队列最前面的任务,然后重新提交被当前的任务
ThreadPoolExecutor.CallerRunsPolicy //由调用线程(提交任务的线程)处理该任务 如果调用线程未关闭的话

自定义拒绝策略

以上的拒绝策略都实现了RejectedExecutionHandler接口,说明可以自己通过实现RejectedExecutionHandler来编写自己的拒绝策略。

四、6种常用的线程池
  • newCachedThreadPool 缓存线程池

在创建新线程时,如果有空闲的线程就重用它们。 使用场景在执行时间短的大量任务是可以使用。

  • newFixedThreadPool

创建一个固定线程数的线程池,并形成队列循环使用。

  • newScheduledThreadPool

可定时调度的线程池,在延迟时间后执行或者定期执行某个线程任务。

  • newSingleThreadExecutor

线程池中只有1个线程执行任务,在该线程出现停止或异常时,会启动一个新的线程进行工作。

  • newSingleScheduleThreadPool

此线程有点结合的意思,是一个只有一个线程的线程池,可用定时任务。

  • newWorkStealingPool

创建一个具有抢占式操作的线程池,stealing 翻译为抢断、窃取的意思,它实现的一个线程池和上面4种都不一样,用的是 ForkJoinPool 类。它是一个并行的线程池,参数中传入的是一个线程并发的数量,这里和之前就有很明显的区别,前面4种线程池都有核心线程数、最大线程数等等,而这就使用了一个并发线程数解决问题。从介绍中,还说明这个线程池不会保证任务的顺序执行,也就是 WorkStealing 的意思,抢占式的工作。

五、线程池的使用 线程池的创建
 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                10,
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue(3),
                new ThreadPoolExecutor.AbortPolicy());
向线程池提交任务
threadPoolExecutor.execute(new WorkTask(task));
关闭线程池
threadPoolExecutor.shutdown();
ThreadPoolExecutorDemo示例
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorDemo {
    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                10,
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue(3),
                new ThreadPoolExecutor.AbortPolicy());

        for (int i = 1; i             
关注
打赏
1663402667
查看更多评论
0.0374s