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

 更新时间:2018年09月03日 16:54:10   作者:大雨如注  
在我们的开发中“池”的概念并不罕见,有数据库连接池、线程池、对象池、常量池等等。下面这篇文章主要给大家介绍了关于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) 方法中有源码如下:

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

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

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

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

 

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

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

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

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

示例: 创建固定线程池 和 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 任务执行流程图:

  

ThreadPoolExecutor 使用注意点说明:

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

总结:

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

相关文章

  • Java使用迭代器Iterator遍历集合

    Java使用迭代器Iterator遍历集合

    Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。本文就来和大家详细聊聊Java如何使用迭代器Iterator实现遍历集合,感兴趣的可以跟随小编一起学习一下
    2022-12-12
  • Java 实现倒计时功能(由秒计算天、小时、分钟、秒)

    Java 实现倒计时功能(由秒计算天、小时、分钟、秒)

    最近做项目遇到这样的需求,天、小时、分钟、秒的数值都是隔开的,服务器端只返回一个时间戳长度,怎么实现这样的功能呢?下面小编给大家带来了Java 实现倒计时功能的方案,需要的朋友参考下吧
    2018-01-01
  • Mybatis源码解析之初始化分析

    Mybatis源码解析之初始化分析

    这篇文章主要介绍了Mybatis源码解析之初始化分析,Mybatis的初始化过程就是mybatis配置文件的解析过程并将解析结果保存到Configuration类。,需要的朋友可以参考下
    2024-01-01
  • 源码分析Java中ThreadPoolExecutor的底层原理

    源码分析Java中ThreadPoolExecutor的底层原理

    这篇文章主要带大家从源码分析一下Java中ThreadPoolExecutor的底层原理,文中的示例代码讲解详细,具有一定的学习价值,需要的可以参考一下
    2023-05-05
  • 一篇文章教带你了解Java Spring之自动装配

    一篇文章教带你了解Java Spring之自动装配

    今天小编就为大家分享一篇关于Spring中的自动装配,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2021-09-09
  • 从前端Vue到后端Spring Boot接收JSON数据的正确姿势(常见错误及问题)

    从前端Vue到后端Spring Boot接收JSON数据的正确姿势(常见错误及问题)

    这篇文章主要介绍了从前端Vue到后端Spring Boot接收JSON数据的正确姿势(常见错误及问题),本文将从前端Vue到后端Spring Boot,详细介绍接收JSON数据的正确姿势,帮助开发人员更好地处理JSON数据,感兴趣的朋友一起看看吧
    2024-02-02
  • SpringBoot项目如何访问jsp页面的示例代码

    SpringBoot项目如何访问jsp页面的示例代码

    本篇文章主要介绍了SpringBoot项目如何访问jsp页面的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 如何理解Java线程池及其使用方法

    如何理解Java线程池及其使用方法

    线程池是首先创建一些线程,它们的集合称为线程池。使用线程池可以提高性能,它在系统启动时创建大量空闲的线程,程序将一个任务传给线程池,它就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务
    2021-06-06
  • Spring Security中的Servlet过滤器体系代码分析

    Spring Security中的Servlet过滤器体系代码分析

    这篇文章主要介绍了Spring Security中的Servlet过滤器体系,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • java数据结构之搜索二叉树

    java数据结构之搜索二叉树

    这篇文章主要为大家详细介绍了java数据结构之搜索二叉树,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论