Java的线程池都是通过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;
}

在Executors工厂类中,Java默认提供了四种类型的线程池。

FixedThreadPool

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

这个线程池的特点:

  • 这是一种线程数量固定的线程池,因为corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads;

  • keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停止掉,不过因为最多只有nThreads个线程,且corePoolSize和maximunPoolSize值一致,所以这个值无法发挥作用;
  • 阻塞队列采用了LinkedBlockingQueue,它是一个无界队列,由于阻塞队列是一个无界队列,因此永远不可能拒绝任务。

CachedThreadPool

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

这个线程池的特点

  • 这是一个线程数量可以“无限”扩大(不能超过整型最大值)的线程池;

  • 比较适合处理执行时间比较小的任务;
  • corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;
  • keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;
  • 采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。

SingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

这个线程池的特点:

  • 只有一个线程,使用了无界队列LinkedBlockingQueue,某种意义上等同于newFixedThreadPool(1);

  • 因为只有一个线程,所以能够保证所有任务是FIFO地执行。

ScheduledThreadPool

public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。

这个线程池的特点:

它接收SchduledFutureTask类型的任务,有两种提交任务的方式:

  • scheduledAtFixedRate

  • scheduledWithFixedDelay

从提交方式可以看出,这个线程池主要处理定时任务或延时任务。

SchduledFutureTask接收的参数:

  • time:任务开始的时间s

  • equenceNumber:任务的序号
  • period:任务执行的时间间隔

它采用DelayQueue存储等待的任务:

  • DelayQueue内部封装了一个PriorityQueue,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;

  • DelayQueue也是一个无界队列;

工作线程的执行过程:

  • 工作线程会从DelayQueue取已经到期的任务去执行;

  • 执行结束后重新设置任务的到期时间,再次放回DelayQueue

#########

Java默认提供的线程池的更多相关文章

  1. Java并发编程之线程池及示例

    1.Executor 线程池顶级接口.定义方法,void execute(Runnable).方法是用于处理任务的一个服务方法.调用者提供Runnable 接口的实现,线程池通过线程执行这个 Runn ...

  2. JAVA基础拾遗-论线程池的线程粒度划分与深浅放置

    摘要:多线程任务处理对提高性能很有帮助,在Java中提供的线程池也方便了对多线程任务的实现.使用它很简单,而如果进行了不正确的使用,那么代码将陷入一团乱麻.因此如何正确地使用它,如以下分享,这个技能你 ...

  3. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  4. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  5. Java多线程-新特性-线程池

    Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序 ...

  6. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  7. java 线程之executors线程池

    一.线程池的作用 平时的业务中,如果要使用多线程,那么我们会在业务开始前创建线程,业务结束后,销毁线程.但是对于业务来说,线程的创建和销毁是与业务本身无关的,只关心线程所执行的任务.因此希望把尽可能多 ...

  8. 深入理解Java自带的线程池和缓冲队列

    前言 线程池是什么 线程池的概念是初始化线程池时在池中创建空闲的线程,一但有工作任务,可直接使用线程池中的线程进行执行工作任务,任务执行完成后又返回线程池中成为空闲线程.使用线程池可以减少线程的创建和 ...

  9. Java并发编程:线程池的使用(转载)

    转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...

随机推荐

  1. Design Patterns Example Code (in C++)

    Overview Design patterns are ways to reuse design solutions that other software developers have crea ...

  2. C++开源库集合

    | Main | Site Index | Download | mimetic A free/GPL C++ MIME Library mimetic is a free/GPL Email lib ...

  3. docker部署oracle

    oracle部署 创建oracle用户 [root@stpass-15 ~]# useradd oracle[root@stpass-15 oracle]# cd oracle [root@stpas ...

  4. Android上传 apk格式文件下载

  5. 详解MySQL第二篇—DML语句

    DML 语句: DML 操作是指对数据库中表记录的操作,主要包括表记录的插入(insert).更新(update).删除(delete)和查(select),是开发人员日常使用最频繁的操作.下面将依次 ...

  6. epson Robot 指令集合

    ******************************************************************* 目的:定义一个整型数据 原型:Integer varName[( ...

  7. IOS自动化定位方式

    原文地址http://blog.csdn.net/wuyepiaoxue789/article/details/77885136 元素属性的介绍 type:元素类型,与className作用一致,如: ...

  8. mysql数据库从删库到跑路之mysql:视图、触发器、事务、存储过程、函数

    mysql:视图.触发器.事务.存储过程.函数 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果 ...

  9. js null, undefined, NaN, ‘’, false, 0, ==, === 全验证

    <html> <head> <meta charset="utf-8" /> </head> <body> <in ...

  10. java环境变量及Eclipse自动编译问题

    环境变量,是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息.例如Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路 ...