线程池

作者: 蜗牛写java | 来源:发表于2019-04-14 22:25 被阅读0次

背景

为什么出现线程池?

  1. 目前计算机CPU均为多核处理器,如果串行执行,必然造成资源上的浪费;
  2. 每次创建线程的时候,和销毁线程的时候,都不是我们程序关心的过程,程序关心的只是执行
  3. 有些业务程序不一定要串行执行,实际上可以并行去执行的;以节约相应时间
  4. 多个线程执行业务,那么怎么管理这些线程呢,是否可以统一管理

使用线程池的好处

  1. 充分利用CPU资源
  2. 提高相应时间
  3. 统一管理线程(比如线程优先级、监控等)

线程池工作原理

线程池,字面上理解肯定有一个池子,这个池子可以是集合或者队列等,java中使用的是队列;池子存在了,那么就需要工作者,就是真实的工作线程;真实的工作线程控制多少呢,真实的工作者的个数;这些都存在了,那么往池子中注入业务是否需要一个入口,java中就是submit

现实中例子:线程池好比一间客服办公室;办公室为池子;办公室必须保证n个接线员以上,n为核心线程数,工位数为最大线程数;接线员为真实的工作线程;电话号码(如10086)位线程池作业提交入口;超出的n个电话业务而等待的电话咨询数,为等待队列;如果等待的人数超出能等待的范围,就添加接线员到新的工位上,接电话;

线程池UML

线程池采用模板模式

线程池UML.png

ThreadPoolExecutor原理图

线程池原理.png
  1. 运行线程数小于 corePoolSize,则创建新的线程来执行(创建新的线程,需要获取全局锁,这时候,其它线程可能在创建或者销毁等)
  2. 如果运行线程数大于等于corePoolSize,则任何加入BlockingQueue
  3. 如果BlockingQueue已满,maximumPoolSize>corePoolSize,则创建新的线程来处理任务(创建线程需要获取全局锁)
  4. 如果队列满,且maximumPoolSize也满,则执行拒绝策略
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
  • corePoolSize : 当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其它空闲的基本线程能够执行任务也会创建线程,一直到任务数>=核心线程数时就不再创建。有prestartAllCoreThread()方法,可以提前创建
  • workQueue:任务队列
    • ArrayBlockingQueue:基于数组实现
    • LinkedBlockingQueue:基于链表实现,吞吐量高于前者
    • SynchronousQueue:一个不存储元素的阻塞队列;没插入操作必须等另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量又高于前者
    • PriorityBlockingQueue:一个具有优先级的无限阻塞队列
  • maximumPoolSize:线程池最大数量;如果队列满了,并且已创建的线程数小于最大线程数,则线程池会创建新的 线程执行任务;如果使用了无界队列的话,这个参数就没有效果
  • threadFactory:设置创建线程的工厂(可以设置创建的线程名称)
  • RejectedExecutionHandler:拒绝策略;当线程池都满了,说明线程池处于饱和状态,那么必须采用一种策略处理新提交的任务。
    • AbortPolicy:直接抛出异常(默认)
    • CallerRunsPolicy:只用调用者所在的线程来运行任务
    • DiscardOldestPolicy:丢弃队列中最近的一个任务,并执行当前任务
    • DiscardPolicy:不处理,直接丢弃掉
  • keepAliveTime:线程池的工作线程空闲后,保存时间
  • TimeUnit:保存时间单位

线程池提交任务

两种方式:

  1. execute() :提交不需要返回值的任务
  2. submit():提交需要返回值的任务,返回类型为Future<Object>

关闭线程池

shutdown,shutdownNow两种方式。原理都是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,无法响应中断的任务可能永远无法终止。

相关文章

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