线程池

作者: 念䋛 | 来源:发表于2020-12-29 10:01 被阅读0次

线程是调度CPU资源的最小单位,线程模型分为KLT模型和ULT模型,Java采用的是KLT模型,java线程与OS(内核)线程保持1:1的映射关系,就是java创建一个线程,内核与之相对应的也会创建一个线程

image.png

线程池的介绍
在并发请求数量多的情况下,而且每个线程的执行时间很短,毫秒级就会执行结束,这样就会频繁的创建和销毁线程,降低了效率,可能出现创建和销毁线程的时间要大于线程执行的时间,线程池的出现就是为了解决上述的问题.
使用场景(绝大多数的场景)
线程执行时间短
线程要处理的任务数多
线程池的优势
重用已有的线程,减少创建和销毁线程
提高相应速度,当任务到达时,不需等待直接使用已有的线程,反应快
提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行同意的分配,调优的监控.

Java 线程池的创建
Java 创建线程池非常重要的类ThreadPoolExecutor其中有4个构造函数,但是最终调用的是7个参数的构造函数

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

7个参数
int corePoolSize, 核心线程数
int maximumPoolSize, 最大线程数 = 非核心线程数 + 核心线程数
long keepAliveTime, 最大允许线程不干活的时间,超过时间则销毁线程,其实就是获取阻塞队列的等待时间,如果在这段时间队列中没有放入新的任务,那当先的线程就会终止,其实就是跳出了while循环, 后续会分析到
TimeUnit unit, keepAliveTime的时间单位
BlockingQueue<Runnable> workQueue, 存放任务数队列
ThreadFactory threadFactory, 线程创建工厂
RejectedExecutionHandler handler 拒绝策略

image.png

线程池的5中状态
ctl变量包含了两个信息,一个是运行状态,一个是线程池的线程数,整型共32位,其中高3位为运行状态,其余29位为线程数

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int RUNNING    = -1 << COUNT_BITS;
private static final int SHUTDOWN   =  0 << COUNT_BITS;
private static final int STOP       =  1 << COUNT_BITS;
private static final int TIDYING    =  2 << COUNT_BITS;
private static final int TERMINATED =  3 << COUNT_BITS;
private static int runStateOf(int c)     { return c & ~CAPACITY; }//当前运行状态
private static int workerCountOf(int c)  { return c & CAPACITY; }//当前线程数
private static int ctlOf(int rs, int wc) { return rs | wc; }//通过状态和线程生成ctl

下面的图片根据高3位可以得出
RUNNING 111
SHUTDOWN 000
STOP 001
TIDYING 010
TERMINATED 011


image.png
image.png
image.png

拒绝策略
new ThreadPoolExecutor.AbortPolicy ();//抛出异常


image.png

new ThreadPoolExecutor.DiscardPolicy (); //什么也没做


image.png
new ThreadPoolExecutor.DiscardOldestPolicy ();//将队列中队头的的任务poll出来,不做处理,就是丢弃掉了
image.png
new ThreadPoolExecutor.CallerRunsPolic();//当前提交任务的线程直接执行,不交给线程池来执行(比如tomcat的线程再执行线程池的execute方法,被拒绝,当使用此拒绝策略时,tomcat的线程直接执行任务)
image.png
image.png

看上图可知,如果使用CallerRunsPolic策略,那么main线程就执行了此任务

相关文章

  • 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/kbcfoktx.html