JUC源码解析
文章平均质量分 95
关于JDK中有关并发的类的源码解析
业精勤而荒嬉
知其然知其所以然
展开
-
JUC源码解析文章目录
基础知识:原子操作的实现:CAS与锁JMM与happens-beforeSynchronizedThreadLocal同步器J.U.C之基——AQS锁ReentrantLockConditionCountDownLatchSemaphoreCyclicBarrierReentrantReadWriteLock并发容器CopyOnWriteArrayListConc...原创 2019-03-23 15:56:32 · 1960 阅读 · 0 评论 -
JUC源码解析-ConcurrentSkipListMap
单线程下若想使用有序的键值对,我们选用 TreeMap,若是考虑到线程安全问题,则可以使用 ConcurrentSkipListMap,它与ConcurrentSkipListSet之间的关系就如 TreeMap 与 TreeSet 之家的关系一样,set 由 map来实现,本篇主要来分析 ConcurrentSkipListMap。底层数据结构是 跳表。...原创 2019-05-12 09:02:21 · 405 阅读 · 0 评论 -
JUC源码解析-线程池-FutureTask
前一篇文章主要从execute方法来分析ThreadPoolExecutor,还有一种提交任务的方式,就是ExecutorService的submit,该方法返回FutureTask,这篇文章就来分析二者的结合。继承图submit方法的主要实现在 AbstractExecuotrService: public <T> Future<T> ...原创 2018-05-10 15:11:00 · 1103 阅读 · 0 评论 -
Java并发之Future模式
本篇是《图解Java多线程设计模式》第九章的读书笔记。Future的意思是未来,假设有一个方法需要花费很长的时间才能获取到运行结果,那么与其一直等待不如先去忙别的,等你完成我再来拿。来看看示例代码:先来看下各个类之间的关系:Data接口RealData 与 FutureData 实现的接口public interface Data { String getContent()...原创 2019-04-07 21:25:02 · 424 阅读 · 0 评论 -
JUC源码解析-线程池-ThreadPoolExecutor
ThreadPoolExecutor首先来看看线程池的主要工作流程图接下来看看源码实现: private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); private static final int COUNT_BITS = Integer.SIZE - 3; p...原创 2018-05-08 12:46:00 · 358 阅读 · 1 评论 -
线程池-相关概念
如果你要开启线程执行任务,你会怎么做?开启一个线程,然后串行执行所有任务一个任务开启一个线程,任务不会再等待,但是线程的创建销毁是需要时间的;线程会消耗系统资源,尤其是内存;线程数的增加在一定范围内会提高吞吐率,但过多只会降低系统的执行速度。由于以上几点原因有了Executor,接下来看看Executor的好处。先来看看几个类:Executor...原创 2018-05-07 11:04:00 · 236 阅读 · 0 评论 -
JUC源码解析-阻塞队列-SynchronousQueue
SynchronousQueue 是一个同步阻塞队列,它的每个插入操作都要等待其他线程相应的移除操作,反之亦然。SynchronousQueue 像是生产者和消费者的会合通道,它比较适合“切换”或“传递”这种场景:一个线程必须同步等待另外一个线程把相关数据传递给它。不同于之前的 ArrayBlockingQueue,LinkedBlockingQueue…对于它们来说生产者线程将数据放入存储空间...原创 2019-03-12 01:47:17 · 285 阅读 · 0 评论 -
JUC源码解析-阻塞队列-DelayQueue
DelayQueue是一个支持延时获取元素的无界阻塞队列。队列使用PriorityQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素。我们可以将DelayQueue运用在以下应用场景:缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从De...原创 2019-03-03 02:39:23 · 241 阅读 · 0 评论 -
JUC源码解析-阻塞队列-PriorityBlockingQueue
PriorityBlockingQueue需要对堆排序有了解,推荐 排序六 堆排序PriorityBlockingQueue 底层是个最小堆。 private static final int DEFAULT_INITIAL_CAPACITY = 11; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE -...原创 2019-03-01 16:53:03 · 214 阅读 · 0 评论 -
JUC源码解析-阻塞队列-迭代器(二)
4,删除remove public void remove() { // assert lock.getHoldCount() == 0; final ReentrantLock lock = ArrayBlockingQueue.this.lock; lock.lock(); try ...原创 2019-02-28 16:56:02 · 273 阅读 · 0 评论 -
JUC源码解析-阻塞队列-迭代器(一)
本篇来分析下阻塞队列里迭代器的实现,以ArrayBlockingQueue源码来分析。首先在开始前想一想,如何实现阻塞队列的迭代器功能?在并发下有些线程在读,有些在改,还有些在使用迭代器遍历,怎么确保安全性?用独占锁将这些操作隔离开,我们看 ArrayBlockingQueue 确实是这么做的。既然安全性得到保障那么还有什么问题是需要考虑的 ?过时数据问题。假设一个线程从此时的 takeI...原创 2019-02-28 16:55:41 · 444 阅读 · 0 评论 -
JUC源码解析-阻塞队列-LinkedBlockingQueue与ArrayBlockingQueue
什么是阻塞队列?阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会阻塞等待,直到队列变为非空或超时。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景。阻塞队列提供了四种处理方法:抛出异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException(“Q...原创 2019-02-28 23:13:07 · 342 阅读 · 0 评论 -
JUC源码解析-ConcurrentHashMap1.8
前言1.8后的ConcurrentHashMap与之前有截然不同的设计,之前是分段锁的思想,通过采用分段锁Segment减少热点域来提高并发效率。1.8利用CAS+Synchronized来保证并发更新的安全,底层采用数组+链表+红黑树的存储结构。在此再一次膜拜Doug Lea大神,高山仰止。1.8的ConcurrentHashMap有6313行代码,之前大概是1000多行。这篇文章也...原创 2018-06-14 20:23:00 · 6793 阅读 · 0 评论 -
JUC源码解析-CopyOnWriteArrayList
利用写时复制来实现的一个线程安全的ArrayList类,任何对内部数组的更改操作都被锁保护,更改操作都是在拷贝的新数组上进行。public class CopyOnWriteArrayList&lt;E&gt; implements List&lt;E&gt;, RandomAccess, Cloneable, java.io.Serializable { private sta...原创 2019-01-29 01:49:34 · 1236 阅读 · 0 评论 -
JUC源码解析-ReentrantReadWriteLock
ReentrantLock是独占锁,只允许一个线程执行;CountDownLatch,Semaphore等是共享锁;它们分别利用了AQS的独占与共享功能;那么如果在读操作远多于写操作的情况下该如何选择?读写锁,之前的文章中介绍了如何自己实现一个读写锁,还实现了重入功能,读读,写写,读写,写读四种重入。现在来看看JUC包下的ReentrantReadWriteLock的实现。先来大致了解下Reen...原创 2018-05-30 16:01:00 · 304 阅读 · 0 评论 -
JUC源码解析-CyclicBarrier
当你有这种需求:想要每执行N个线程后就执行某个任务,那么你就可以用CyclicBarrier。举个例子:四个线程,每个线程在执行完自己的任务后停下来等待其它三个线程执行完任务,全部执行完后,四个线程继续往下执行。public class CyclicBarrierTest { static class Writer extends Thread { priv...原创 2018-05-19 20:51:00 · 297 阅读 · 0 评论 -
JUC源码解析-Semaphore
Semaphore信号量是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。开始前建议先看之前AQS的文章,以及很多共享锁的代码在之前CountDownLatch文章里介绍过了。看看例子:public class SemaphoreTrain { static class Worker extends Thread { pri...原创 2018-05-17 17:11:00 · 1504 阅读 · 0 评论 -
JUC源码解析-CountDownLatch
CountDownLatch允许一个或多个线程等待其它线程完成操作。CountDownLatch的构造函数接收一个int类型的参数作为计数器,想等待N个任务线程完成就传N。当countDown方法被调用N就会减一,await方法会阻塞当前线程直到N变为0。主要的功能就是通过await()方法来阻塞线程,然后等待计数器减少到0了,再唤起那些等待的线程继续;即你想要某些线程等待另一些线程执行完...原创 2018-05-16 23:57:00 · 375 阅读 · 0 评论 -
JUC源码解析-Condition
生产者消费者实例:public class ProductorCustom<T> { private final ReentrantLock lock = new ReentrantLock(); private Condition putButFull = lock.newCondition(); private Condition tackButEm...原创 2018-05-14 17:59:00 · 390 阅读 · 0 评论 -
JUC源码解析-ReentrantLock
AQS是同步器的基础,要先了解AQS的实现使用实例:Lock lock = new ReentrantLock();Condition condition = lock.newCondition();lock.lock();try { while(条件判断表达式) { condition.wait(); } // 处理逻辑} finally { l...原创 2018-05-14 14:53:00 · 387 阅读 · 0 评论 -
JUC源码解析——AQS
在java.util.concurrent包(下称j.u.c包)中,大部分的同步器(例如锁,屏障等等)都是基于AbstractQueuedSynchronizer(下称AQS类)这个类来构建的;它是个抽象的FIFO队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架。J.U.C包下的同步器的实现都主要依赖于以下几个功能:内部同步状态的管理 同步状态的更新和检查操作 且至少有...原创 2018-05-02 12:43:00 · 823 阅读 · 0 评论 -
ThreadLocal源码解析
什么是ThreadLocal?它是属于线程自己的小仓库。关于它的使用与介绍看这一篇:ThreadLocal的介绍与使用关于ThreadLocal的原理,理清四个角色关系:Thread,ThreadLocal,ThreadLocalMap,Entry:在Thread中有个变量指向ThreadLocalMap ThreadLocal.ThreadLocalMap thread...原创 2019-04-09 11:05:42 · 457 阅读 · 0 评论 -
ThreadLocal的介绍与使用
本篇是《图解Java多线程设计模式》第十一章的读书笔记。有一个储物室,里面有很多储物柜。每个人拿着自己的钥匙去开自己的储物柜,虽然进同一个储物室,但彼此互不干扰。这就是 Thread-Local Storage 线程中的局部存储空间。来看一个例子:每个线程将信息打印到自己的日志文件中。TSLog :打印类,每个线程都有自己的 TSLog 对象,向自己的日志文件中打印信息。public cl...原创 2019-04-08 09:49:52 · 423 阅读 · 0 评论 -
Synchronized
我将《Java并发编程的艺术》里关于synchronized的相关知识总结为如下的思维导图,更清楚的解释请去看该书的2.2章。原创 2019-03-23 10:35:21 · 237 阅读 · 0 评论 -
理解volatile
特性可见性:对一个volatile变量的读,总能看到任意线程对这个volatile变量最后的写。原子性:对任意单个volatile变量的读/写具有原子性。如何实现的?对volatile的写操作其汇编代码会多出一步带lock前缀的指令:0x01a3de24: **lock** addl $0x0,(%esp);该指令在多核处理器下引发两件事情:1,将当前处理器缓存行的数据写回到系统内...原创 2019-04-06 06:21:48 · 278 阅读 · 0 评论 -
JMM与happens-before
首先关于Java并发的通信机制是基于共享内存实现的,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信,这对程序员是透明的,我们需要理解其工作机制,以防止内存可见性问题,从而编写出正确同步的代码。同步指用于控制不同线程间操作发生相对顺序的机制,我们需要显式的指定方法或代码块需要在线程之间互斥执行。由于Java的这种通信方式,一个线程要跟另一个通信,何时将共享变量刷新到内存,另一...原创 2019-03-23 15:37:59 · 1425 阅读 · 1 评论 -
原子操作的实现:CAS与锁
首先什么是原子操作?原子本意是“不能被进一步分割的最小粒子”,而原子操作意为”不可被中断的一个或一系列操作”;处理器如何实现原子操作?首先处理器会自动保证基本的内存操作的原子性:处理器保证从系统内存当中读取或者写入一个字节是原子的,意思是当一个处理器读取一个字节时,其他处理器不能访问这个字节的内存地址。 总线锁保证原子性:所谓总线锁就是使用处理器提供的一个LOCK#信号,当一个处理器...原创 2018-04-30 12:27:00 · 996 阅读 · 0 评论