`
edgar108
  • 浏览: 32462 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

ThreadPoolExecutor流程

阅读更多

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
用给定的初始参数创建新的 ThreadPoolExecutor
参数:
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
threadFactory - 执行程序创建新线程时使用的工厂。
handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
抛出:
IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小于 0,或者 maximumPoolSize 小于等于 0,或者 corePoolSize 大于 maximumPoolSize。
NullPointerException - 如果 workQueue threadFactory  handler 为 null。

FixThreadPool创建:

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
ThreadPoolExecutor的corePoolSize和maximumPoolSize都被设置为nThreads,当线程池中的线程数大于corePoolSize时,keepAliveTime为多余的空闲线程等待新任务的最长时间,超出这个时间后多余的线程将被终止。这里把keepAliveTime设置为0L,意味着多余的空闲线程会被立刻终止。
 
ThreadPoolExecutor的  execute():
(1) 如果当前运行的线程数少于 corePoolSize,则创建新线程来执行任务。
(2) 在线程池完成预热之后(当前运行的线程数等于corePoolSize),将任务加入LinkedBlockingQueue。
(3) 线程执行完1中的任务后,会在循环中反复从LinkedBlockingQueue获取任务来执行。
 
 
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) //addWorker 创建任务并start
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) { //等于corePoolSize后加入队列
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
addWorker方法创建worker,即实际工作线程,当实际工作线程达到corePoolSize后,不再创建worker,后续的任务加入阻塞队列,现有的worker的 runWorker方法从队列中不断的获取任务。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
FixThreadPool 使用无界队列LinkedBlockingQueue作为线程池的工作队列(容量为Integer.MAX_VALUE),使用无界队列会:
(1) 当线程池中的线程数达到corePoolSize后,新任务将在无界队列中等待,因此线程池中的线程数不会超过corePoolSize。
(2) 由于第一点,maximumPoolSize和 keepAliveTime是无效的参数。
(3) 由于使用无界队列,运行中的FixedThreadPool(未执行方法shutdown()或shutdownNow()) 不会拒绝任务(不会调用RejectedExecutionHandler.rejectedExecution 方法)

 

分享到:
评论

相关推荐

    源码深度分析线程池中Worker线程的执行流程

    文中我们深度分析了线程池执行任务的核心流程,在ThreadPoolExecutor类的addWorker(Runnable, boolean)方法中,使用CAS安全的更新线程的数量之后,接下来就是创建新的Worker线程执行任务

    第7章-JUC多线程v1.1.pdf

    主要流程: 1.判断核心线程池是否已满, 如果不是, 则创建线程执行任务 2.如果核心线程池满了, 判断队列是否满了, 如果队列没满, 将任务放在队列中 3.如果队列满了, 则判断线程池是否已满, 如果没满, 创建线程执行...

    在Android线程池里运行代码任务实例

    流程是,添加一个任务到线程池的工作队列,当有线程可用时(执行完其他任务,空闲,或者还没执行任务),ThreadPoolExecutor会从队列里取任务,并在线程里运行。 本课同时向你展示了如何停止正在运行的任务。 在线程池...

    java线程池概念.txt

    线程安全,并发的知识有加深认知;当然,现在用过的东西并不是代表以后还能娴熟...至此线程池基本的流程完了; 再说说我在项目中的使用: MyExtendThreadPoolExecutor 继承了 ThreadPoolExecutor,并覆盖了其中的一些...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    11.3.1 ThreadPoolExecutor 407 11.3.2 线程池的分类 410 第12章 Bitmap的加载和Cache 413 12.1 Bitmap的高效加载 414 12.2 Android中的缓存策略 417 12.2.1 LruCache 418 12.2.2 DiskLruCache 419 12.2.3 ...

    Android多线程:完全解析线程池ThreadPool原理&使用

    线程池中有6个核心参数,具体如下上述6个参数的配置决定了线程池的功能,具体设置时机=创建线程池类对象时传入ThreadPoolExecutor类=线程池的真正实现类开发者可根据不同需求配置核心参数,从而实现自定义线程池注:...

    Android开发艺术探索

     11.3.1 ThreadPoolExecutor / 407  11.3.2 线程池的分类 / 410  第12章 Bitmap的加载和Cache / 413  12.1 Bitmap的高效加载 / 414  12.2 Android中的缓存策略 / 417  12.2.1 LruCache / 418  12.2.2 ...

    高级java笔试题-itresource:程序开发技术资源集合

    heavyz的Tomcat学习笔记(包括启动流程分析、启动脚本分析) ] () [ java8 新特性讲解系列文章 ] () [ Java 从Jar文件中动态加载类 ] () [ Java并发源码分析 - ThreadPoolExecutor ] () [ java ClassLoader 基本原理 ]...

    J2SE技术总结-Java学习精华教程-电子书

    流程控制 ..........数组的使用 .....字符串和正则表达式 ..........字符串 ..........正则表达式 .....类和对象 ..........类的对象的使用 ..........自定义类 ..........自定义时使用修饰符 .....继承和多态 ........

Global site tag (gtag.js) - Google Analytics