随笔分类 - java.util.concurrent包源码分析
摘要:《java.util.concurrent 包源码阅读》系列文章已经全部写完了。开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边写文章。由于水平有限,在阅读源代码的时候,分析得也比较浅显,还有很多地方自己也没有研究明白,有的地方显得语焉不详...
阅读全文
摘要:这一部分来分析Phaser关于线程等待的实现。所谓线程等待Phaser的当前phase结束并转到下一个phase的过程。Phaser提供了三个方法:// 不可中断,没有超时的版本public int awaitAdvance(int phase);// 可以中断,没有超时的版本public int ...
阅读全文
摘要:Phaser是JDK7新添加的线程同步辅助类,作用同CyclicBarrier,CountDownLatch类似,但是使用起来更加灵活:1. Parties是动态的。2. Phaser支持树状结构,即Phaser可以有一个父Phaser。Phaser的构造函数涉及到两个参数:父Phaser和初始的p...
阅读全文
摘要:接下来看看调用ForkJoinTask的join方法都发生了什么: public final V join() { // doJoin方法返回该任务的状态,状态值有三种: // NORMAL, CANCELLED和EXCEPTIONAL // join...
阅读全文
摘要:在写前面两篇文章23和24的时候自己有很多细节搞得不是很明白,这篇文章把Fork和Work-Stealing相关的源代码重新梳理一下。首先来看一些线程池定义的成员变量:关于scanGuard:volatile int scanGuard;private static final int SG_UNI...
阅读全文
摘要:仔细看了Doug Lea的那篇文章:A Java Fork/Join Framework 中关于Work-Stealing的部分,下面列出该算法的要点(基本是原文的翻译):1. 每个Worker线程都维护一个任务队列,即ForkJoinWorkerThread中的任务队列。2. 任务队列是双向队列,...
阅读全文
摘要:上篇文章一直追踪到了ForkJoinWorkerThread的pushTask方法,仍然没有办法解释Fork的原理,那么不妨来看看ForkJoinWorkerThread的run方法: public void run() { Throwable exception = null;...
阅读全文
摘要:JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人解释:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果。这样就能使用多线程的方式来执行一个任务。JDK7引入的Fork/Join有三个核心类:ForkJoinPool,执行任务的线程池ForkJo...
阅读全文
摘要:CyclicBarrier是一个用于线程同步的辅助类,它允许一组线程等待彼此,直到所有线程都到达集合点,然后执行某个设定的任务。现实中有个很好的例子来形容:几个人约定了某个地方集中,然后一起出发去旅行。每个参与的人就是一个线程,CyclicBarrier就是那个集合点,所有人到了之后,就一起出发。C...
阅读全文
摘要:DelayQueue有序存储Delayed类型或者子类型的对象,没当从队列中取走元素时,需要等待延迟耗完才会返回该对象。所谓Delayed类型,因为需要比较,所以继承了Comparable接口:public interface Delayed extends Comparable { long...
阅读全文
摘要:前面讲ScheduledThreadPoolExecutor曾经重点讲到了DelayedWorkQueue,这里说的PriorityBlockingQueue其实是DelayedWorkQueue的简化版本,实现了按序排列元素的功能。也就是说PriorityBlockingQueue是维护一个按序排...
阅读全文
摘要:Exchanger可以看做双向数据传输的SynchronousQueue,即没有生产者和消费者之分,任意两个线程都可以交换数据。在JDK5中Exchanger被设计成一个容量为1的容器,存放一个等待线程,直到有另外线程到来就会发生数据交换,然后清空容器,等到下一个到来的线程。从JDK6开始,Exch...
阅读全文
摘要:学过操作系统的朋友都知道信号量,在java.util.concurrent包中也有一个关于信号量的实现:Semaphore。从代码实现的角度来说,信号量与锁很类似,可以看成是一个有限的共享锁,即只能被有限数量的线程使用的共享锁。因为存在计数,因此Semaphore的构造函数有参数permits来设定...
阅读全文
摘要:SynchronousQueue是一种很特别的BlockingQueue,任何一个添加元素的操作都必须等到另外一个线程拿走元素才会结束。也就是SynchronousQueue本身不会存储任何元素,相当于生产者和消费者手递手直接交易。SynchronousQueue有一个fair选项,如果fair为t...
阅读全文
摘要:这篇文章主要说说DelayedWorkQueue。在ScheduledThreadPoolExecutor使用DelayedWorkQueue来存放要执行的任务,因为这些任务是带有延迟的,而每次执行都是取第一个任务执行,因此在DelayedWorkQueue中任务必然按照延迟时间从短到长来进行排序的...
阅读全文
摘要:ScheduledThreadPoolExecutor是ThreadPoolExecutor的子类,同时实现了ScheduledExecutorService接口。public class ScheduledThreadPoolExecutor extends ThreadPoolEx...
阅读全文
摘要:这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭。先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int corePoolSize, int ...
阅读全文
摘要:接着说worker线程是如何工作的。ThreadPoolExecutor有一个成员类叫Worker,所起到的作用就是线程池worker线程的作用。private final class Worker extends AbstractQueuedSynchronizer implements Runn...
阅读全文
摘要:先来看ThreadPoolExecutor的execute方法,这个方法能体现出一个Task被加入到线程池之后都发生了什么: public void execute(Runnable command) { if (command == null) throw...
阅读全文
摘要:AbstractExecutorService对ExecutorService的执行任务类型的方法提供了一个默认实现。这些方法包括submit,invokeAny和InvokeAll。注意的是来自Executor接口的execute方法是未被实现,execute方法是整个体系的核心,所有的任务都是在...
阅读全文