标签分类
技术文章
当前位置:主页 > 计算机编程 > java > java中ThreadPoolExecutor常识汇总

java中ThreadPoolExecutor知识点总结

  • 发布时间:
  • 作者:码农之家原创
  • 点击:197

java中ThreadPoolExecutor常识汇总

这篇文章主要知识点是关于java,ThreadPoolExecutor,常识,java中ThreadPoolExecutor常识汇总,java线程池对象ThreadPoolExecutor的深入讲解 的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

阿里巴巴Java开发手册
  • 类型:Java开发大小:27.5 MB格式:PDF出版:电子工业出版社作者:杨冠宝
立即下载

线程池技术在并发时经常会使用到,java中的线程池的使用是通过调用ThreadPoolExecutor来实现的。ThreadPoolExecutor提供了四个构造函数,最后都会归结于下面这个构造方法:

// 七个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

这些参数的意义如下:

  • corePoolSize:该线程池中核心线程数最大值
  • maximumPoolSize: 该线程池中线程总数最大值
  • keepAliveTime:该线程池中非核心线程闲置超时时长
  • unit:keepAliveTime的单位
  • workQueue:阻塞队列BlockingQueue,维护着等待执行的Runnable对象
  • threadFactory:创建线程的接口,需要实现他的Thread newThread(Runnable r)方法。
  • RejectedExecutionHandler:饱和策略,最大线程和工作队列容量且已经饱和时execute方法都将调用RejectedExecutionHandler 。

ThreadPoolExecutor工作流程

流程图如下:

java中ThreadPoolExecutor常识汇总

大致过程陈述为:

  1. 向线程池中添加任务,当任务数量少于corePoolSize时,会自动创建thead来处理这些任务;
  2. 当添加任务数大于corePoolSize且少于maximmPoolSize时,不在创建线程,而是将这些任务放到阻塞队列中,等待被执行;
  3. 接上面2的条件,且当阻塞队列满了之后,继续创建thread,从而加速处理阻塞队列;
  4. 当添加任务大于maximmPoolSize时,根据饱和策略决定是否容许继续向线程池中添加任务,默认的饱和策略是AbortPolicy(直接丢弃)。

线程池中使用的阻塞队列

  • ArrayBlockingQueue:基于数组结构的有界阻塞队列,构造函数一定要传大小,FIFO(先进先出);
  • LinkedBlockingQueue:无界,默认大小65536(Integer.MAX_VALUE),当大量请求任务时,容易造成内存耗尽。
  • SynchronousQueue:同步队列,是一个特殊的BlockingQueue,它没有容量(这是因为在SynchronousQueue中,插入将等待另一个线程的删除操作,反之亦然)。具体可以参考:《Java SynchronousQueue Examples(译)》
  • PriorityBlockingQueue: 优先队列,无界。
  • DelayedWorkQueue:这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务

阻塞队列常见的方法如下表所示:

 

方法名 说明 注意
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素 如果队列为空,则阻塞

 

常见四种线程池

  • newCachedThreadPool
  • newFixedThreadPool
  • newSingleThreadExecutor
  • newScheduledThreadPool

 

线程池 使用的阻塞队列 线程池大小 超时
CachedThreadPool SynchronousQueue(队列长度无限 可增加,最大值Integer.MAX_VALUE 默认60秒超时
FixedThreadPool LinkedBlockingQueue(队列长度无限) 可指定nThreads,固定数量 不会超时
newSingleThreadExecutor LinkedBlockingQueue(队列长度无限), 固定为1 不超时
newScheduledThreadPool DelayedWorkQueue 可增加,最大值Integer.MAX_VALUE 不超时

 

它们通过Executors以静态方法的方式直接调用,实质上是它们最终调用的是ThreadPoolExecutor的构造方法,也就是本文最前面那段代码。

注:KeepAliveTime=0的话,表示不等待

《阿里巴巴java开发手册》中建议线程池不使用 Executors 去创建,而是通过 ThreadPoolExecutor的方式,这样的处理方式让写的人员更加明确线程池的运行规则,规避资源耗尽的风险。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

java线程池对象ThreadPoolExecutor的深入讲解

使用线程池的好处

1、降低资源消耗

可以重复利用已创建的线程降低线程创建和销毁造成的消耗。

2、提高响应速度

当任务到达时,任务可以不需要等到线程创建就能立即执行。

3、提高线程的可管理性

线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控

ThreadPoolExecutor 介绍:

java 提供的线程池类;

ThreadPoolExecutor 作用:

两个作用:

1,用于分离执行任务和当前线程;

2,主要设计初衷:重复利用Thread 对象;

ThreadPoolExecutor 使用:

实例化:

public ThreadPoolExecutor(int corePoolSize,
        int maximumPoolSize,
        long keepAliveTime,
        TimeUnit unit,
        BlockingQueue<Runnable> workQueue) {
  this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
    Executors.defaultThreadFactory(), defaultHandler);
 }

这是ThreadPoolExecutor的构造方法之一,传入参数最少,以下是参数说明:

corePoolSize  : 设置线程池的线程核心数量;该参数作用:当向线程池中添加的任务数量小于核心数量时,线程池将优先创建新的线程,而不是重用之前已存在的线程(不管该线程可用与否);

源码佐证,ThreadPoolExecutor 的 execute(Runnable) 方法中有源码如下:

java线程池对象ThreadPoolExecutor的深入讲解

maximumPoolSize : 设置线程池可创建最大线程数量;该参数作用:用于限制线程池无限制的创建线程;

源码佐证,ThreadPoolExecutor 的 addWorker(Runnable ,boolean) 方法中有源码如下:

java线程池对象ThreadPoolExecutor的深入讲解

keepAliveTime  : 设置线程池被创建线程的存活时间;

源码佐证,ThreadPoolExecutor 的 getTask()方法中有源码如下;源码说明:创建的线程将从任务队列中获取一个新的任务,在keepAliveTime时间之后如果还未获取到任务,将关闭该线程;

java线程池对象ThreadPoolExecutor的深入讲解 

unit :设置线程池线程存活时间的时间单位;

workQueue :设置线程池用于存放任务的队列;

注意:ThreadPoolExecutor线程池是否创建新的线程不仅仅依赖于corePoolSize变量,还依赖于任务队列的offer(E) 方法所返回的值;比如:想要创建一个cache线程池,就依赖于一个特殊的任务队列:SynchronousQueue<E>;

源码佐证,ThreadPoolExecutor 的execute(Runnable) 方法中有源码如下:

java线程池对象ThreadPoolExecutor的深入讲解

示例: 创建固定线程池 和 cache线程池;

固定线程池,将corePoolSize 和 maximumPoolSize 设置相同即可,在Executors.newFixedThreadPool(10)有源码示例:

 public static ExecutorService newFixedThreadPool(int nThreads) {
  return new ThreadPoolExecutor(nThreads, nThreads,
          0L, TimeUnit.MILLISECONDS,
          new LinkedBlockingQueue<Runnable>());
 }

cacahe线程池,需要传入特殊的BlockingQueue对象,该对象需要在offer是返回false,并能够在poll方法中监听到offer进入的任务;java 提供了一个SynchronousQueue类,该类就是这样一个对象;在Executors.newCachedThreadPool()方法中,有源码示例:

 public static ExecutorService newCachedThreadPool() {
  return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
          60L, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>());
 }

常用方法提示:

  void execute(Runnable command) : 任务提交方法;线程池将顺序执行所提交的所有方法;

  void shutdown() : 停止后续任务提交,但执行完当前线程池中所有任务;该方法的作用:线程池将中断当前所有空闲的线程,但不保证一定中断(可查看Thread的interrupt方法);那么工作中的线程将继续工作,直到完成;

源码:

public void shutdown() {
  final ReentrantLock mainLock = this.mainLock;
  mainLock.lock();
  try {
   checkShutdownAccess();
   advanceRunState(SHUTDOWN);
   interruptIdleWorkers(); 、//中断所有空闲的线程
   onShutdown(); // hook for ScheduledThreadPoolExecutor
  } finally {
   mainLock.unlock();
  }
  tryTerminate();
 }

  List<Runnable> shutdownNow() : 立即终止线程池;该方法的作用:线程池将中断所有创建的线程,但不保存一定中断;线程池将所有剩余的任务从任务队列中移除,不在执行,并保存在一个List中返回给用于;

方法源码:

public List<Runnable> shutdownNow() {
  List<Runnable> tasks;
  final ReentrantLock mainLock = this.mainLock;
  mainLock.lock();
  try {
   checkShutdownAccess();
   advanceRunState(STOP);
   interruptWorkers();
   tasks = drainQueue();
  } finally {
   mainLock.unlock();
  }
  tryTerminate();
  return tasks;
 }

ThreadPoolExecutor 任务执行流程图:

java线程池对象ThreadPoolExecutor的深入讲解  

ThreadPoolExecutor 使用注意点说明:

清晰需要使用的是那种类型的线程池,在实例化ThreadPoolExecutor时,传入的参数不同创建出来的线程池也将不同;尤其注意传入BlockingQueue参数,如果需要使用cache线程池,请确保BlockingQueue的offer方法反回false;可以参见SynchronousQueue类;

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对码农之家的支持。

以上就是本次给大家分享的全部知识点内容总结,大家还可以在下方相关文章里找到儿童python编程入门书籍推、 解决axios.interceptors.respon、 vue项目中使用md5加密以及、 等java文章进一步学习,感谢大家的阅读和支持。

上一篇:java对synchronized的优化知识点总结

下一篇:Java中List集合的遍历的知识点总结

展开 +

收起 -

学习笔记
网友NO.636627

Java ThreadPoolExecutor 线程池的使用介绍

Executors Executors 是一个Java中的工具类. 提供工厂方法来创建不同类型的线程池. 从上图中也可以看出, Executors的创建线程池的方法, 创建出来的线程池都实现了 ExecutorService 接口. 常用方法有以下几个: newFixedThreadPool(int Threads) : 创建固定数目线程的线程池, 超出的线程会在队列中等待. newCachedThreadPool() : 创建一个可缓存线程池, 如果线程池长度超过处理需要, 可灵活回收空闲线程(60秒), 若无可回收,则新建线程. newSingleThreadExecutor() : 创建一个单线程化的线程池, 它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行. 如果某一个任务执行出错, 将有另一个线程来继续执行. newScheduledThreadPool(int corePoolSize) : 创建一个支持定时及周期性的任务执行的线程池, 多数情况下可用来替代Timer类. Executors 例子 newCachedThreadPool 线程最大数为 Integer.MAX_VALUE , 当我们往线程池添加了 n 个任务, 这 n 个任务都是一起执行的. ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(new Runnable() { @Override public void run() { for (;;) { try { Thread.currentThread().sleep(1000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } }); cachedThreadPool.execute(new Runnable() { @Override public void run() { for (;;) { try { ……

网友NO.277154

Java自带定时任务ScheduledThreadPoolExecutor实现定时器和延时加载功能

java.util.concurrent.ScheduledThreadPoolExecutor 是JDK1 .6之后自带的包,功能强大,能实现定时器和延时加载的功能 各类功能和处理方面优于 Timer 1、定时器: ScheduledThreadPoolExecutor 有个scheduleAtFixedRate(command, initialDelay, period, unit) ;方法 command: 执行的线程(可自己New一个) initialDelay:初始化执行的延时时间 period: 时间间隔 unit : 时间类型(如TimeUnit.SECONDS: 秒的方式执行,TimeUnit.DAYS : 天数的方式执行) 具体代码: public static void main(String[] args) { stThread.scheduleAtFixedRate(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println(new Date()); } }, 20, 2, TimeUnit.SECONDS); } 2、延时处理 ScheduledThreadPoolExecutor 有个schedule(callable, delay, unit) ; 方法 callable:回调方法 delay:延时时间 unit:时间类型,同定时器的unit一样 具体代码: stThread.schedule((RolePrvlegeTask)SpringUtils.getBean("rolePrvlegeTask"), 1, TimeUnit.SECONDS); 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对码农之家的支持。如果你想了解更多相关内容请查看下面相关链接 ……

<
1
>

Copyright 2018-2019 xz577.com 码农之家

版权责任说明