1. 提纲

1)线程池的模块结构

2)示例&原理解析

2. 问题

1)线程池包含哪些东西

2)线程池的运作原理

3)调度线程池的运作原理

4)线程池怎么实现FixRate,FixDelay,他们之间的区别

5)任务怎么取消

3. 源码解析

3.1 线程池框架

接口简介:

java.util.concurrent.Executor:执行器,执行方法

java.util.concurrent.ExecutorService:(执行服务)包含服务的生命周期

java.util.concurrent.ScheduledExecutorService:(调度相关的服务)

辅助类:

java.util.concurrent.Executors:

核心实现类:

java.util.concurrent.ThreadPoolExecutor:(普通的线程池实现类)

java.util.concurrent.ScheduledThreadPoolExecutor:(调度的核心实现类)

java.util.concurrent.ForkJoinPool

完成服务:

java.util.concurrent.CompletionService:

java.util.concurrent.ExecutorCompletionService:

3.2 ThreadPoolExecutor源码剖析

1)构造器

核心数量,任务队列容器,存活时间,线程工厂,处理器

ThreadPoolExecutor.execute()方法源码

    public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
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);
}

ThreadPoolExecutor.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);
}
}

3.3 ScheduledThreadPoolExecutor

1)

2)FixRate和FixDelay的区别

        /**
* Sets the next time to run for a periodic task.
*/
private void setNextRunTime() {
long p = period;
if (p > 0)
time += p;
else
time = triggerTime(-p);
}

FixRate严格按照设定的时间

FixDelay按照上一个线程执行完成的时间间隔

FixRate: 21:40,21:41,21:42

FixDelay:21:40,21:43

    void reExecutePeriodic(RunnableScheduledFuture<?> task) {
if (canRunInCurrentRunState(true)) {
       //此处没有捕获异常,如果单个任务发生异常,会导致后续任务无法继续执行
super.getQueue().add(task);
if (!canRunInCurrentRunState(true) && remove(task))
task.cancel(false);
else
ensurePrestart();
}
}

【图灵学院10】高并发之java线程池源码分析的更多相关文章

  1. java线程池源码分析

    我们在关闭线程池的时候会使用shutdown()和shutdownNow(),那么问题来了: 这两个方法又什么区别呢? 他们背后的原理是什么呢? 线程池中线程超过了coresize后会怎么操作呢? 为 ...

  2. java多线程----线程池源码分析

    http://www.cnblogs.com/skywang12345/p/3509954.html 线程池示例 在分析线程池之前,先看一个简单的线程池示例. 1 import java.util.c ...

  3. java多线程——线程池源码分析(一)

    本文首发于cdream的个人博客,点击获得更好的阅读体验! 欢迎转载,转载请注明出处. 通常应用多线程技术时,我们并不会直接创建一个线程,因为系统启动一个新线程的成本是比较高的,涉及与操作系统的交互, ...

  4. Java线程池源码解析

    线程池 假如没有线程池,当存在较多的并发任务的时候,每执行一次任务,系统就要创建一个线程,任务完成后进行销毁,一旦并发任务过多,频繁的创建和销毁线程将会大大降低系统的效率.线程池能够对线程进行统一的分 ...

  5. Java线程池源码及原理

    目录 1 说明 1.1类继承图 2 线程池的状态 3 源码分析 3.1完整的线程池构造方法 3.2 ctl 3.3 任务的执行 3.3.1 execute(Runnable command) 3.3. ...

  6. 线程池之ThreadPoolExecutor线程池源码分析笔记

    1.线程池的作用 一方面当执行大量异步任务时候线程池能够提供较好的性能,在不使用线程池的时候,每当需要执行异步任务时候是直接 new 一线程进行运行,而线程的创建和销毁是需要开销的.使用线程池时候,线 ...

  7. Java并发编程中线程池源码分析及使用

    当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...

  8. java线程池源码的理解

    线程池 新建线程和切换线程的开销太大了,使用线程池可以节省系统资源. 线程池的关键类:ThreadPoolExecutor. 该类中包含了大量的多线程与并发处理工具,包括ReentrantLock.A ...

  9. 线程池之ScheduledThreadPoolExecutor线程池源码分析笔记

    1.ScheduledThreadPoolExecutor 整体结构剖析. 1.1类图介绍 根据上面类图图可以看到Executor其实是一个工具类,里面提供了好多静态方法,根据用户选择返回不同的线程池 ...

随机推荐

  1. mysql函数之三:find_in_set() 函数 返回str在字符串集strlist中的序号

    如果字符串str是在的strlist组成的N子串的字符串列表,返回值的范围为1到N. FIND_IN_SET(str,strlist) 如果字符串str是在的strlist组成的N子串的字符串列表,返 ...

  2. UE4材质初探

    转自:http://www.unrealchina.net/portal.php?mod=view&aid=233 UE4的材质表面上看起来很简单,可是到了用的时候却总是没有办法实现好的效果. ...

  3. 发任务找不到test-unit报错

    发任务的时候因找不到gem包test-unit报错, 出错行: require 'test/unit' require 'test/unit/testresult' 解决办法如下 1.通过命令查看ge ...

  4. Microsoft Sync Framework下的快速开发同步程序

    Microsoft Sync Frameworks简称MSF,是一个综合的同步平台,MSF支持应用程序,服务,设备的在线以及离线同步.MSF主要有以下几个部件组成:     * Sync Servic ...

  5. 重新认识synchronized(下)

    synchronized既保证原子性,又保证内存可见性,是一种线程同步的方式,是锁机制的一种java实现.synchronized的实现基于JVM底层,JVM是基于monitor实现的,而monito ...

  6. 2015.1.4 判断鼠标点击DataGridView的第几行还是空白处

    public int GetRowIndexAt(int mouseLocation_Y) { if (dvaw.FirstDisplayedScrollingRowIndex < 0) { r ...

  7. 清除SUN服务器部件的suspect状态

    对于suspect状态的部件,可以用setchs命令清除其状态.如果ScApp的版本在5.20.15之前,需要进入service模式后才能使用setchs命令.如果ScApp版本 升级到5.20.15 ...

  8. 部署和调优 2.1 squid正向代理

    安装squid yum install -y squid Squid 官方网站为 http://www.squid-cache.org 打开注释掉的 cache_dir ufs / 缓存目录的位置,大 ...

  9. Tiny4412 u-boot分析(2)u-boot启动流程

    从大方面来说,u-boot的启动分成两个阶段,第一个阶段主要的职责是准备初始化的环境,主要有以下几点 ①设置异常向量表 ②把CPU的工作模式设置为SVC32模式 ③关闭中断.MMU和cache ④关闭 ...

  10. C语言学习笔记--函数与指针

    1. 函数类型 (1)C 语言中的函数有自己特定的类型,这个类型由返回值.参数类型和参数个数共同决定.如 int add(int i,int j)的类型为 int(int,int). (2)C 语言中 ...