hreadPoolExecutor机制 
一、概述 
1、ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调度,线程池管理等等服务; 
2、Executors方法提供的线程服务,都是通过参数设置来实现不同的线程池机制。 
3、先来了解其线程池管理的机制,有助于正确使用,避免错误使用导致严重故障。同时可以根据自己的需求实现自己的线程池

二、核心构造方法讲解 
下面是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;
}

构造方法参数讲解

参数名 作用
corePoolSize 核心线程池大小
maximumPoolSize 最大线程池大小
keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使得核心线程有效时间
TimeUnit keepAliveTime时间单位
workQueue 阻塞任务队列
threadFactory 新建线程工厂
RejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理

看这个参数很容易让人以为是线程池里保持corePoolSize个线程,如果不够用,就加线程入池直至maximumPoolSize大小,如果还不够就往workQueue里加,如果workQueue也不够就用RejectedExecutionHandler来做拒绝处理。

但实际情况不是这样,具体流程如下:

1)当池子大小小于corePoolSize就新建线程,并处理请求

2)当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理

3)当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理

4)另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁

内部结构如下所示:

从中可以发现ThreadPoolExecutor就是依靠BlockingQueue的阻塞机制来维持线程池,当池子里的线程无事可干的时候就通过workQueue.take()阻塞住。

其实可以通过Executes来学学几种特殊的ThreadPoolExecutor是如何构建的。

三、Executors提供的线程池配置方案

1、构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理

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

2、构造一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁

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

3、构造一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行

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

4、构造有定时功能的线程池,配置corePoolSize,无界延迟阻塞队列DelayedWorkQueue;有意思的是:maximumPoolSize=Integer.MAX_VALUE,由于DelayedWorkQueue是无界队列,所以这个值是没有意义的

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
} public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
} public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}

转自:http://blog.csdn.net/u014756827/article/details/52213313

http://blog.csdn.net/cutesource/article/details/6061229

【Java 线程的深入研究4】ThreadPoolExecutor运转机制详解的更多相关文章

  1. ThreadPoolExecutor运转机制详解

    ThreadPoolExecutor运转机制详解 - 走向架构师之路 - 博客频道 - CSDN.NET 最近发现几起对ThreadPoolExecutor的误用,其中包括自己,发现都是因为没有仔细看 ...

  2. Java并发编程(07):Fork/Join框架机制详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Fork/Join框架 Java提供Fork/Join框架用于并行执行任务,核心的思想就是将一个大任务切分成多个小任务,然后汇总每个小任务 ...

  3. 【移动端兼容问题研究】javascript事件机制详解(涉及移动兼容)

    前言 这篇博客有点长,如果你是高手请您读一读,能对其中的一些误点提出来,以免我误人子弟,并且帮助我提高 如果你是javascript菜鸟,建议您好好读一读,真的理解下来会有不一样的收获 在下才疏学浅, ...

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

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

  5. Java线程锁,synchronized、wait、notify详解

    (原) JAVA多线程这一块有点绕,特别是对于锁,对锁机制理解不清的话,程序出现了问题也很难找到原因,在此记录一下线程的执行以及各种锁. 1.JAVA中,每个对象有且只有一把锁(lock),也叫监视器 ...

  6. Java线程编程中isAlive()和join()的使用详解

    一个线程如何知道另一线程已经结束?Thread类提供了回答此问题的方法. 有两种方法可以判定一个线程是否结束.第一,可以在线程中调用isAlive().这种方法由Thread定义,它的通常形式如下: ...

  7. 转 Java虚拟机5:Java垃圾回收(GC)机制详解

    转 Java虚拟机5:Java垃圾回收(GC)机制详解 Java虚拟机5:Java垃圾回收(GC)机制详解 哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无 ...

  8. [转]JAVA环境变量JAVA_HOME、CLASSPATH、PATH设置详解

    [转] JAVA环境变量JAVA_HOME.CLASSPATH.PATH设置详解 - dreamman的日志 - 网易博客http://blog.163.com/dreamman_yx/blog/st ...

  9. Java NIO 的前生今世 之四 NIO Selector 详解

    Selector Selector 允许一个单一的线程来操作多个 Channel. 如果我们的应用程序中使用了多个 Channel, 那么使用 Selector 很方便的实现这样的目的, 但是因为在一 ...

随机推荐

  1. javascript浮点数转换成整数三种方法

    将浮点数转换成整数方法有很多,分享三种常用方法. Summary 暂时我就想到3个方法而已.如果读者想到其他好用方法,也可以交流一下 parseInt位运算符Math.floor Math.ceil ...

  2. [na]tftp从linux下载文件

    1,背景: 当我们ssh到一台linux上时候,从linux上下载一些文件,方案如下: 1.1通过sftp:通过win7 ftp客户端连接到linux去下载文件. 1.2通过tftp 2,问题 有些l ...

  3. 并行开发系列 Plinq等

    http://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html

  4. Ubantu MySQL数据库操作

    用户管理: 1.新建用户: >CREATE USER name IDENTIFIED BY 'ssapdrow'; 2.更改密码: >SET PASSWORD FOR name=PASSW ...

  5. 每日英语:Why Are Fractions Key To Future Math Success?

    Many students cruise along just fine in math until fourth grade or so. Then, they hit a wall -- frac ...

  6. hdoj1241 Oil Deposits

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  7. MySQL PLSQL Demo - 001.创建、调用、删除过程

    drop procedure if exists p_hello_world; create procedure p_hello_world() begin select sysdate(); end ...

  8. LINQ架构简单描述

    写在前面的话:课堂上老师只是简单提了一下LINQ,当时听着老师对它的描述,感觉非常神奇,不用去操作繁琐的SQL语句了,读取数据库的操作居然能向写C#代码一样方便,但是一直没有机会去学习使用它. LIN ...

  9. 一款基于jquery漂亮的按钮

    之前为大家分享了好多css3实现的按钮.今天给大家分享一款基于jquery漂亮的按钮.这款按钮背景下用了一张图片.当鼠标经过的时候背景用半透明div遮住.一起看下效果图: 在线预览   源码下载 实现 ...

  10. 统一处理jquery ajax请求过程中的异常错误信息的机制

    当jQuery ajax向服务器发送请求,服务器发生异常,比如:400.403.404.500等异常,服务器将异常响应给客户端,此时的ajax可以获取异常信息并进行处理,但此时我们一般是跳转到与异常编 ...