![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java并发库源码解析
xingfeng_coder
路漫漫其修远兮,吾将上下而求索
Gitbook地址:https://xingfeng.gitbook.io/hust
简书地址:https://www.jianshu.com/u/57f41372c68e
展开
-
1.8ConcurrentHashMap源码分析
ConcurrentHashMap是一个线程安全的HashMap,ConcurrentHashMap和HashMap的底层数据结构相同,都是数组+链表+红黑树;但是hash方法、键、值不允许为null和Hashtable一样,并且都是线程安全的,只不过实现同步的细节上有所差别。尽管支持高并发的读写,但是ConcurrentHashMap在读操作时不会加锁。关于HashMap和Hashtable...原创 2019-12-07 22:38:35 · 520 阅读 · 0 评论 -
CopyOnWriteArrayList源码分析
概述Java自1.5后提供了两个写时复制的容器,分别是CopyOnWriteArrayList和CopyOnWriteArraySet。其思路就是在执行会改变底层数据的结构时,首先加锁,然后复制得到一个新的数据,在这个数据上做修改,最后再将原来的数据引用指向这个新的数据,最后释放锁;而读操作则不需要修改。这是一种读写分离的思想,读和写不同的容器,读的是旧容器,写的是新容器。 由于CopyOnWri原创 2017-09-27 14:57:32 · 620 阅读 · 0 评论 -
深入理解Callable
概述Callable和Runnbale一样代表着任务,区别在于Callable有返回值并且可以抛出异常。其使用如下: public class CallableDemo { static class SumTask implements Callable<Long> { @Override public Long call() throws Exception原创 2017-08-22 18:34:42 · 27397 阅读 · 1 评论 -
JDK1.7ConcurrentHashMap源码分析
机制:分段加锁 SegmentSegment的定义如下: /** * Segments are specialized versions of hash tables. This * subclasses from ReentrantLock opportunistically, just to * simplify some locking and avoid原创 2017-07-31 18:29:07 · 789 阅读 · 1 评论 -
ThreadPoolExecutor源码分析
一、线程和任务的概念首先区分概念,任务和线程。可以简单理解为任务为Runnable,线程为Thread。ThreadPoolExecutor内部维持的是线程池,因为创建线程比较耗时耗资源。而内部维护任务使用的是BlockingQueue。二、ThreadPoolExecutor源码2.1 ctl变量ThreadPoolExecutor中有一个ctl的变量,声明如下: private final原创 2017-03-01 09:07:56 · 3696 阅读 · 1 评论 -
深入理解阻塞队列(三)——LinkedBlockingQueue源码分析
LinkedBlockingQueue是一个基于链表实现的可选容量的阻塞队列。队头的元素是插入时间最长的,队尾的元素是最新插入的。新的元素将会被插入到队列的尾部。 LinkedBlockingQueue的容量限制是可选的,如果在初始化时没有指定容量,那么默认使用int的最大值作为队列容量。 概述类继承关系LinkedBlockingQueue的继承关系如下图: 可以参考深入理解阻塞队列(二原创 2017-06-12 09:01:59 · 9939 阅读 · 1 评论 -
深入理解阻塞队列(四)——LinkedBlockingDeque源码分析
LinkedBlockingDeque是一个基于链表的双端阻塞队列。和LinkedBlockingQueue类似,区别在于该类实现了Deque接口,而LinkedBlockingQueue实现了Queue接口。该类的继承关系如下图: 本文将与LinkedBlockingQueue进行比较,关于LinkedBlockingQueue可以参考:深入理解阻塞队列(三)——LinkedBlocki原创 2017-06-20 09:31:01 · 15107 阅读 · 2 评论 -
深入理解阻塞队列(二)——ArrayBlockingQueue源码分析
在深入理解阻塞队列(一)——基本结构中,介绍了BlockingQueue这一接口的子类以及子接口。本文主要就其中的一个实现类:ArrayBlockingQueue进行源码分析,分析阻塞队列的阻塞是如何实现的。 概述ArrayBlockingQueue底层是使用一个数组实现队列的,并且在构造ArrayBlockingQueue时需要指定容量,也就意味着底层数组一旦创建了,容量就不能改变了,因此Arr原创 2017-06-05 09:20:20 · 2964 阅读 · 7 评论 -
深入理解阻塞队列(一)——基本结构
BlockingQueue是一个继承自Queue的接口,在Queue的队列基础上增加了阻塞操作。简单来说,就是在在BlockingQueue为空时从队头取数据将会被阻塞,因为此时还没有数据可取,一旦队列中有数据了,取数据的线程就会释放得到了数据;如果BlockingQueue有容量限制且满了,那么插入数据的线程将会阻塞,知道队列中有空闲位置可以插入数据了,才会释放。经过上面一段描述,可以发现这不就是原创 2017-05-31 09:14:03 · 9284 阅读 · 0 评论 -
深入理解读写锁—ReadWriteLock源码分析
ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。 所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。 读写锁比互斥锁允许对于共享数据更大程度的并发。每次只能有一个写线程,但是同时可以有多个线程并发地读数据。ReadWriteLock适用于读多写少的并发原创 2017-04-24 09:00:54 · 71890 阅读 · 9 评论 -
深入理解Semaphore
使用Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有实际的许可证这个对象,Semaphore只是维持了一个可获得许可证的数量。 Semaphore经常用于限制获取某种资源的线程数量。下面举个例子,比如说操场...原创 2017-04-17 16:02:28 · 51065 阅读 · 14 评论 -
AbstractQueuedSynchronizer详解(一)——分析ReentrantLock源码
官方文档如是说AQS提供了一个框架,一个FIFO的等待队列和一个代表状态的int值。子类需要定义改变这个状态的protected方法、定义什么状态表示获取到状态以及释放状态。该类中其中方法提供所有入队和阻塞机制。子类可以保存其他状态,但是需要使用getState、setState和compareAndSetState方法来原子性地读取更新状态值。 AQS用于一群线程为了得到某个资源,但是同一时刻,原创 2017-03-16 15:40:15 · 1881 阅读 · 0 评论 -
AbstractQueuedSynchronizer详解(二)——CountDownLatch源码分析
在AbstractQueuedSynchronizer详解(一)——分析ReentrantLock源码中介绍了其内部结构以及独占模式的一个例子:ReentrantLock。本篇文章介绍其共享模式的一个例子:CountDownLatch。 CountDownLatch的使用CountDownLatch是一个工具类,用于使一个或多个线程等待另一系列线程完成操作,也就是说一些线程在另外一些完成之后才能继原创 2017-04-01 09:21:07 · 977 阅读 · 0 评论 -
ThreadLocal源码分析
一、概念ThreadLocal提供线程本地变量。这些变量与普通变量不同,每个线程有自己的一份拷贝。ThreadLocal实例典型用法是在类中作为私有的静态域,用与线程绑定状态(比如,用户ID或者事务ID)。 简而言之,每个线程第一次获取该值后,之后在线程内部就可以随意操作该变量,但是这并不影响其他线程,因为每个线程一旦拥有了该变量后,就会有一份拷贝。public class ThreadId {原创 2017-03-06 09:09:05 · 773 阅读 · 0 评论