ThreadPoolExecutor组成

ThreadPoolExecutor的核心构造函数:

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

根据构造方法可以看才ThreadPoolExecutor主要分为以下几个部分:

  1. corePoolSize:核心线程池能容纳的线程数
  2. maximumPoolSize:线程池最大能容纳的线程数(实际是当核心线程池满了之后会进行扩容maxSize - coreSize)
  3. keepAliveTime: 当线程执行完毕之后等待被销毁的时间
  4. workQueue:存放等待执行的任务,是一个BlockingQueue。
  5. ThreadFactory: 线程的构造方法
  6. RejectedExecutionHandler: 线程被拒绝加入线程池时执行的策略

等待队列 BlockingQueue

  • ArrayBlockingQueue : 基于数组的先进先出队列,构造时必须指明大小;
  • LinkedBlockingDeque : 基于链表的队列,如果构造时没有指明大小,则默认为Integer.MAX_VALUE;
  • SynchronousQueue : 一次只会执行一个Thread的队列。

线程池新入线程

线程池的策略,当来新线程时:

  1. 如果线程池中有空闲线程,就复用空闲线程。
  2. 如果没有空闲线程,就将新线程加入等待队列。
  3. 如果来的线程太多,等待队列也满了,就临时扩容到maxPoolSize,相当于使用了一个临时线程池来使用。
  4. 如果扩容还是无法满足,就执行拒绝策略。具体的拒绝策略根据创建时的handler决定。
  5. 线程池通过使用一个Woker负责循环从等待队列中获取线程执行。

ThreadPoolExecutor用法

1. 直接实例化一个

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

2. 使用Executorsnew****Pool()方法创建ExecutorService:

每一个new****Pool方法实质也是调用ThreadPoolExecutor的构造方法,只是传入的参数是设定好的。

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
  • FixedThreadPool : 核心线程池大小和最大线程池一样,缓存队列为LinkedBlokingQueue,超出线程池满了之后进入的线程都会被加入等待队列。
  • ScheduledThreadPool : 核心线程池大小用户决定,最大线程池大小为Integer.MAX_VALUE。等待队列为:DelayedWorkQueue
  • SingleThreadExecutor : 核心线程池为0,意味着新的线程马上就会被创建。

ThreadPoolExecutor和ExecutorService的区别

首先ExecutorExecutorService都是接口,ThreadPoolExecutor是类。

通过Executors.new****Pool创建线程池返回的都是ExecutorService的实例,相当于是调用的ThreadPoolExecutor的构造方法,返回的是它的父类AbstracExecutorService的实例。AbstracExecutorService又是实现了ExecutorService接口的抽象类。

ThreadPoolExecutor理解的更多相关文章

  1. java线程池ThreadPoolExecutor理解

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...

  2. 009-ThreadPoolExecutor运转机制详解,线程池使用1-newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool

    一.ThreadPoolExecutor理解 为什么要用线程池: 1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务. 2.可以根据系统的承受能力,调整线程池中工作线线程的数 ...

  3. android线程池ThreadPoolExecutor的理解

    android线程池ThreadPoolExecutor的理解 线程池 我自己理解看来.线程池顾名思义就是一个容器的意思,容纳的就是ThreadorRunable, 注意:每一个线程都是需要CPU分配 ...

  4. ThreadPoolExecutor的一点理解

    整个ThreadPoolExecutor的任务处理有4步操作: 第一步,初始的poolSize < corePoolSize,提交的runnable任务,会直接做为new一个Thread的参数, ...

  5. Java 并发系列(一) ThreadPoolExecutor源码解析及理解

    ThreadPoolExecutor 它是线程池最核心的类, 这里对核心的方法做简要的剖析(会持续更新),以加深对线程池运行原理的理解. 1. 核心成员变量及相关方法 // ctl非常重要,用整型表示 ...

  6. 深入理解java线程池—ThreadPoolExecutor

    几句闲扯:首先,我想说java的线程池真的是很绕,以前一直都感觉新建几个线程一直不退出到底是怎么实现的,也就有了后来学习ThreadPoolExecutor源码.学习源码的过程中,最恶心的其实就是几种 ...

  7. ThreadPoolExecutor的一点理解 专题

    corePoolSize(maxActiveThreadSize):线程池大小,决定着新提交的任务是新开线程云执行还是放到任务队列中,也是线程池的最最核心的参数.一般线程池开始时是没有线程的,只有当任 ...

  8. 多线程学习笔记-深入理解ThreadPoolExecutor

    java多线程中,线程池的最上层接口是Executor,ExecutorService实现了Executor,是真正的管理线程池的接口,ThreadPoolExecutor间接继承了ExecutorS ...

  9. 理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize

    我们知道,受限于硬件.内存和性能,我们不可能无限制的创建任意数量的线程,因为每一台机器允许的最大线程是一个有界值.也就是说ThreadPoolExecutor管理的线程数量是有界的.线程池就是用这些有 ...

随机推荐

  1. 手机访问pc版网站自动跳转为手机版页面

    1.PC版首页</head>标签前加上以下脚本 <script src="/tools/browser_redirect.ashx"></script ...

  2. 【codeforces 514C】Watto and Mechanism(字符串hash)

    [题目链接]:http://codeforces.com/contest/514/problem/C [题意] 给你n个字符串; 然后给你m个询问;->m个字符串 对于每一个询问字符串 你需要在 ...

  3. 【codeforces 768E】Game of Stones

    [题目链接]:http://codeforces.com/contest/768/problem/E [题意] NIM游戏的变种; 要求每一堆石头一次拿了x个之后,下一次就不能一次拿x个了; 问你结果 ...

  4. Codeforces 263C. Appleman and Toastman

    C. Appleman and Toastman time limit per test  2 seconds memory limit per test  256 megabytes input  ...

  5. mybatis源码阅读-初始化六个工具(六)

    六个基本工具图集 图片来源:https://my.oschina.net/zudajun/blog/668596 ObjectFactory 类图 接口定义 public interface Obje ...

  6. nyoj_33_蛇形填数_201308221636

    蛇形填数时间限制:3000 ms  |  内存限制:65535 KB 难度:3描述 在n*n方陈里填入1,2,...,n*n,要求填成蛇形.例如n=4时方陈为:10 11 12 19 16 13 28 ...

  7. P1464 Function 洛谷

    https://www.luogu.org/problem/show?pid=1464 题目描述 对于一个递归函数w(a,b,c) 如果a<=0 or b<=0 or c<=0就返回 ...

  8. WEB安全:SQL注入

    SQL注入是站点和web应用程序中最常见的安全漏洞. 这样的恶意技术有非常多应用场景, 但(SQL注入)一般是指在数据输入的地方注入代码以利用数据库应用程序中的安全漏洞. SQL注入在接收用户输入的接 ...

  9. HDU 2348

    DFS+博弈. 假设存在两数(x,y),且x<y.对于(x+ky,y)k>=2,只能转移向两种状态(x+y,y),或者(x,y).而对于(x+y,y)只能向(x,y)转移,那么,可知,无论 ...

  10. linux下查看监听port相应的进程

    使用netstat查看进程PID [root@test ~]# netstat -anp|grep 5001 tcp 0 0 :::5001 :::* LISTEN 12886/java 之后各位看官 ...