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类;

总结:

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

(0)

相关推荐

  • java对象转型实例分析

    本文实例讲述了java对象转型的概念,分享给大家供大家参考.具体方法如下: 对象转型(casting)注意事项如下: 1.一个基类的引用类型变量可以"指向"其子类的对象. 2.一个基类的引用不可以访问其子类对象新增加的成员(属性和方法). 3.可以使用 引用变量 instanceof 类名 来判断该引用型变量所"指向"的对象是否属于该类或该类的子类. 4.子类的对象可以当做基类的对象来使用称作向上转型(upcasting),反之成为向下转型(downcasting)

  • java中对象的序列化与反序列化深入讲解

    引言: 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是为了解决在对对象流进行读写操作时所引发的问题. 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对 象,当有 10万用户并发访问,就有可能出现10万个Session对

  • 详细讲述Java中的对象转型

    向上转型:子类对象转为父类,父类可以是接口.公式:Father f = new Son();Father是父类或接口,son是子类. 向下转型:父类对象转为子类.公式:Son s = (Son)f; 我们将形参设为父类Animal类型,当执行test.f(c)时,内存情况如下图: c作为Cat类型传入,Animal a作为形参,相当于执行了Animal a = new Cat(),这时a和c同时指向Cat对象,但此时a不能访问Cat类扩展的数据成员,所以再将a强转成Cat类型即可.如果不存在这样

  • 实例分析java对象中浅克隆和深克隆

    引言: 在Object基类中,有一个方法叫clone,产生一个前期对象的克隆,克隆对象是原对象的拷贝,由于引用类型的存在,有深克隆和浅克隆之分,若克隆对象中存在引用类型的属性,深克隆会将此属性完全拷贝一份,而浅克隆仅仅是拷贝一份此属性的引用.首先看一下容易犯的几个小问题 clone方法是Object类的,并不是Cloneable接口的,Cloneable只是一个标记接口,标记接口是用用户标记实现该接口的类具有某种该接口标记的功能,常见的标记接口有三个:Serializable.Cloneable

  • 实例分析java对象的序列化和反序列化

    引言: 序列化是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其带你过去的状态写入到临时或持储存区,反序列化就是重新创建对象的过程,此对象来自于临时或持久储存区. 序列化的作用: 就好比如存储数据到数据库,将一些数据持久化到数据库中,而有时候需要将对象持久化,虽然说将对象状态持久化的方式有很多,但是java给我们提供了一种很便捷的方式,那就是序列化,序列化可以实现对象到文件之间的直接转换,实现细节对我们隐藏. 具体的三种用途: •将对象的状态信息持久化保存到硬盘上 •将对

  • Java对象序列化操作详解

    本文实例讲述了Java对象序列化操作.分享给大家供大家参考,具体如下: 当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再恢复为Java对象. 只能将支持 java.io.Serializable 接口的对象写入流中.每个 serializable 对象的类都被编码,编码内容包括类名和类签名.对象的字段值和数组值,以及从初始对象中引用的其他所有对象

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

    使用线程池的好处 1.降低资源消耗 可以重复利用已创建的线程降低线程创建和销毁造成的消耗. 2.提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行. 3.提高线程的可管理性 线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配.调优和监控 ThreadPoolExecutor 介绍: java 提供的线程池类: ThreadPoolExecutor 作用: 两个作用: 1,用于分离执行任务和当前线程: 2,主要设计初衷:重复利用T

  • 超详细讲解Java线程池

    目录 池化技术 池化思想介绍 池化技术的应用 如何设计一个线程池 Java线程池解析 ThreadPoolExecutor使用介绍 内置线程池使用 ThreadPoolExecutor解析 整体设计 线程池生命周期 任务管理解析 woker对象 Java线程池实践建议 不建议使用Exectuors 线程池大小设置 线程池监控 带着问题阅读 1.什么是池化,池化能带来什么好处 2.如何设计一个资源池 3.Java的线程池如何使用,Java提供了哪些内置线程池 4.线程池使用有哪些注意事项 池化技术

  • 在spring boot中使用java线程池ExecutorService的讲解

    1. 认识java线程池 1.1 在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.需处理的任务的数量大 1.2 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存 1.3 线程池包括以下四个基本组成部分: 1.线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务: 2.工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以

  • java线程池ThreadPoolExecutor类使用详解

    在<阿里巴巴java开发手册>中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量:另一方面线程的细节管理交给线程池处理,优化了资源的开销.而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool().newSingleThreadExecutor().newCachedThreadPool(

  • Java 线程池ThreadPoolExecutor源码解析

    目录 引导语 1.整体架构图 1.1.类结构 1.2.类注释 1.3.ThreadPoolExecutor重要属性 2.线程池的任务提交 3.线程执行完任务之后都在干啥 4.总结 引导语 线程池我们在工作中经常会用到.在请求量大时,使用线程池,可以充分利用机器资源,增加请求的处理速度,本章节我们就和大家一起来学习线程池. 本章的顺序,先说源码,弄懂原理,接着看一看面试题,最后看看实际工作中是如何运用线程池的. 1.整体架构图 我们画了线程池的整体图,如下: 本小节主要就按照这个图来进行 Thre

  • java线程池ThreadPoolExecutor类使用小结

    目录 一.workQueue任务队列 二.拒绝策略 三.ThreadFactory自定义线程创建 四.ThreadPoolExecutor扩展 五.线程池线程数量 在<阿里巴巴java开发手册>中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量:另一方面线程的细节管理交给线程池处理,优化了资源的开销.而线程池不允许使用Executors去创建,而要通过ThreadPoolExecutor方式,这一方面是由于jdk中E

  • Java线程池 ThreadPoolExecutor 详解

    目录 一 为什么要使用线程池 二 线程池原理详解 2.1 线程池核心组成 2.2 Execute 原理 三 线程池的使用 3.1 创建线程池 3.1.1 自定义线程池 3.1.2 功能线程池 3.1.3 功能线程池存在的问题 3.2 向线程池提交任务 3.3 关闭线程池 3.4 自定义线程池需要考虑因素 一 为什么要使用线程池 对于操作系统而言,创建一个线程的代价是十分昂贵的, 需要给它分配内存.列入调度,同时在线程切换时要执行内存换页,清空 CPU 缓存,切换回来时还要重新从内存中读取信息,破

  • Java线程池ThreadPoolExecutor源码深入分析

    1.线程池Executors的简单使用 1)创建一个线程的线程池. Executors.newSingleThreadExecutor(); //创建的源码 public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new Linke

  • java 线程之对象的同步和异步(实例讲解)

    一.多线程环境下的同步与异步 同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去. package com.jalja.org.thread.demo01; public class Thread02 { public synchronized void method1(){ System.out.println("method1:"+Thread.currentThread().getName()); try { T

  • java线程池ThreadPoolExecutor的八种拒绝策略示例详解

    目录 池化设计思想 线程池触发拒绝策略的时机 JDK内置4种线程池拒绝策略 拒绝策略接口定义 AbortPolicy(中止策略) DiscardPolicy(丢弃策略) DiscardOldestPolicy(弃老策略) 第三方实现的拒绝策略 Dubbo 中的线程拒绝策略 Netty 中的线程池拒绝策略 ActiveMQ 中的线程池拒绝策略 PinPoint 中的线程池拒绝策略 谈到 Java 的线程池最熟悉的莫过于 ExecutorService 接口了,jdk1.5 新增的 java.uti

随机推荐