Java中线程池原理以及参数说明 -- 转载

本篇博文为转载,转载连接如下:
https://www.cnblogs.com/guofuangela/p/14381030.html
https://segmentfault.com/a/1190000019319050

线程池的类结构

在这里插入图片描述1.Executor:线程池的核心接口,负责线程的创建使用和调度的根接口

public interface Executor {
   // Executor 的定义非常简单,就定义了线程池最本质要做的事,执行任务。
    void execute(Runnable command);
}

2.ExecutorService: Executor的子接口,线程池的主要接口, 提供基本功能。
ExecutorService 也是个接口,不过他算是把线程池的框架搭出来了,告诉要实现它的线程池必须提供的一些管理线程池的方法。
3.AbstractExecutorService 是普通的线程池执行器
4.ScheduledExecutorService 是定时任务线程池。
实现类
1.ThreadPoolExecutor:ExecutorService的实现类,负责线程池的创建使用。
2.ScheduledThreadPoolExecutor:继承 ThreadPoolExecutor,并实现 ScheduledExecutorService接口,既有线程池的功能,又具有线程调度功能。
3 Executors:线程池的工具类,负责线程池的创建。

static ExecutorService newFixedThreadPool(int nThreads) 
       //创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
static ExecutorService newCachedThreadPool() 
      //创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
static ExecutorService newSingleThreadExecutor() 
       //创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 
static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 
      //创建一个定长线程池,支持定时及周期性任务执行。 

线程池的基本原理

在这里插入图片描述
第一步便是我们将我们的任务提交给线程池
如果线程池中线程数小于核心线程数,则创建一个新的线程来执行该任务。否则进入步骤3
提交任务时,线程池中的空闲的线程数为0并且线程数等于核心线程数,则观察线程池中的任务队列是否已满,如果未满则将任务添加到任务队列,否则进入步骤4
如果最大线程数大于核心线程数,并且总线程数小于最大线程数,则创建一个新的线程来执行该任务。否则进入步骤5
当任务队列已满时,就执行拒绝策略(后续详解拒绝策略)

线程池核心类ThreadPoolExecutor参数和拒绝策略

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
                          //省略具体的代码内容
}

参数 说明
corePoolSize 核心线程数
maximumPoolSize 最大线程数,一般大于等于核心线程数
keepAliveTime 线程存活时间(针对最大线程数大于核心线程数时,非核心线程)
unit 存活时间单位,和线程存活时间配套使用
workQueue 任务队列
threadFactory 创建线程的工程
handler 拒绝策略

workQueue主要有三种类型:
ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue。

第一个是有界阻塞队列,第二个是无界阻塞队列,当然也可以为其指定界限大小,第三个是同步队列,对于ArrayBlockingQueue,其是需要指定队列大小的,当队列存满了任务线程池就会创建新的线程执行任务,对于LinkedBlockingQueue,如果其指定界限,那么和ArrayBlockingQueue区别不大,如果其不指定界限,那么其理论上是可以存储无限量的任务的,实际上能够存储Integer.MAX_VALUE个任务(还是相当于可以存储无限量的任务),此时由于LinkedBlockingQueue是永远无法存满任务的,因而maxPoolSize的设定将没有意义,一般其会设定为和corePoolSize相同的值。对于SynchronousQueue,其内部是没有任何结构存储任务的,当一个任务添加到该队列时,当前线程和后续添加任务的线程都会被阻塞,直至有一个线程从该队列中取出任务,当前线程才会被释放,因而如果线程池使用了该队列,那么一般corePoolSize都会设计得比较小,maxPoolSize会设计得比较大,因为该队列比较适合大量并且执行时间较短的任务的执行;

拒绝策略有以下几种
拒绝策略 说明
AbortPolicy 为java线程池默认的阻塞策略,不执行此任务,而且直接抛出一个运行时异常。
DiscardOldestPolicy 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
DiscardPolicy 也是丢弃任务,但是不抛出异常
CallerRunsPolicy 由调度线程处理该任务

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值