java并发编程
文章平均质量分 92
BballChen
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
JAVA并发包(二十五):Semaphore
Semaphore也是高并发中控制并发量的工具,它维护一系列的运行许可。每个线程运行之前来获取许可,许可的数量有限,只有获得的线程才能继续运行,否则阻塞等待。通过前面对CountDownLatch的学习,现在来理解Semaphore应该会轻松点。一、基本代码结构public class Semaphore implements java.io.Serializable { /** S...原创 2020-02-05 21:11:11 · 265 阅读 · 0 评论 -
JAVA并发包(二十四):CyclicBarrier
CyclicBarrier中文翻译是循环栏栅,用在并发中,可以理解为它要求指定数量的线程必须都到达某个指定位置时才能往下走。为什么叫循环,因为这个栏栅可以多次循环使用,一次放开栏栅后,所有线程都会通过。然后关闭栏栅,后面就可以接着使用。生活中的例子是,比如一个团队准备去爬山,约定在某个时间地点,要每个成员都到达才会出发。先到达的只能在集合地等待了,只要最后一个成员到达,大家才会出发。代码例子如下...原创 2020-02-05 18:55:55 · 459 阅读 · 0 评论 -
JAVA并发包(二十三):CountDownLatch
CountDownLatch用在一个操作需要等待其他多个操作都执行完毕之后才会执行的场合,可以理解有一个计数器,某个动作需要等待计数器减到0的时候会发运行。用汽车等待乘客的例子好理解些,比如一辆小汽车,必须等待满3个乘客才会发车,我们来看看例子: public static void main(String[] args) throws InterruptedException { ...原创 2020-02-05 15:43:16 · 271 阅读 · 0 评论 -
JAVA并发包(二十二):CopyOnWriteArraySet
CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的,它能保证数组里的对象是唯一的。由于在上篇文章中对CopyOnWriteArrayList做了较详细的讲解,这里就简要分析下CopyOnWriteArraySet的原理。一、代码结构CopyOnWriteArraySet继承了AbstractSet,它具备Set属性和方法,最重要的是保证集合里对象唯一,这...原创 2020-02-05 13:10:01 · 381 阅读 · 0 评论 -
JAVA并发包(二十一):CopyOnWriteArrayList
CopyOnWriteArrayList实现了List接口,从名字可以看出它在写入数据的时候复制一份数组。CopyOnWriteArrayList是数组结构,写数据可以大概描述为首先获取锁,接着把旧数组的数据复制到新数组,然后往新数组里插入数据,最后把list的数组替换为新数组。读数据不会加锁,直接读取数组的数据。下面我们从代码层面去理解。一、基本代码结构以下代码可以看出CopyOnWri...原创 2020-02-05 12:31:01 · 353 阅读 · 0 评论 -
JAVA并发包(二十):ConcurrentHashMap
ConcurrentHashMap也是并发环境中常见的Map,如果在高并发中没有排序等特别的需要,我们可以优先选择ConcurrenHashMap存储key-value键值对。ConcurrentHashMap一般有两个版本的实现,jdk7(包括7)之前是Segment+链表的数据结构,jdk8(包括8)之后是synchronized+cas+红黑树的数据结构。下面我们先来比较下各种常见Map...原创 2020-02-05 00:16:23 · 341 阅读 · 0 评论 -
JAVA并发包(十九):ConcurrentSkipListSet
ConcurrentSkipListSet基于ConcurrentSkipListMap实现的,与HashSet基于HashSet实现相像。阅读该篇文章之前请先学习ConcurrentSkipListMap,下面我将简要介绍下ConcurrentSkipListSet实现原理。一、代码结构从ConcurrentSkipListSet的构造器中,可看到实例化时会初始化m对象为Concurren...原创 2020-02-04 19:56:33 · 1823 阅读 · 0 评论 -
JAVA并发包(十八):ConcurrentSkipListMap
ConcurrentSkipListMap内部是一种新的数据结构,可以叫它是跳跃链表结构,其节点相当于是excel中的表格,用了存储空间换取操作时间的,其查询时间复杂度是log(n)。另外插入时已做好节点的排序,遍历的时候就是排好序的了。ConcurrentSkipListMap是可以并发操作的map,其key和value不能为null。其插入操作会比较耗性能,可以用在并发环境,插入少查询多的场...原创 2020-02-04 16:59:01 · 814 阅读 · 0 评论 -
JAVA并发包(十七):ConcurrentLinkedQueue
ConcurrentLinkedQueue的直接翻译叫做并发链表队列,它以自旋非阻塞的方式实现队列的功能,内部维护链表结构,没有容量的限制。可以结合LinkedBlockingQueue原理去理解ConcurrentLinkedQueue,其中的最重要区别就是线程是否阻塞等待。下面我们还是从其内部代码结构去学习ConcurrentLinkedQueue。一、内部代码结构从以下基本代码可以看到...原创 2020-02-04 00:58:56 · 2164 阅读 · 3 评论 -
JAVA并发包(十六):LinkedBlockingDeque
LinkedBlockingDeque是双端阻塞队列,它跟LinkedBlockingQueue的区别在于它可以做到后进先出,也就是实现栈的功能,本篇文章我们主要来看看它是如何实现后进先出的。一、基本代码结构从以下代码结构中可以看到,它跟LinkedBlockingQueue没什么差别,可以猜测它也是用重入锁控制并发访问。另外有两个等待队列用来阻塞队列满了或者空了的情况。public cla...原创 2020-01-29 15:44:15 · 271 阅读 · 0 评论 -
JAVA并发包(十五):ScheduledThreadPoolExecutor
通过之前对线程池和延迟队列的研究,我们现在来学习ScheduleThreadPoolExecutor(简称STPE)就比较轻松了。可以把STPE理解为这样一个线程池,它里面的任务可以延迟一次性执行(叫做定时任务),也可以每隔一个周期重复执行(周期任务)。STPE继承了ThreadPoolExecutor类,所以它的线程池运作原理就是ThreadPoolExecutor那一套,只是任务队列用了延迟...原创 2020-01-29 14:05:54 · 365 阅读 · 0 评论 -
JAVA并发包(十四):DelayQueue
DelayQueue可以说是加了定时的PriorityBlockingQueue,它也是最小堆的结构,不过节点的取出必须要等到延迟的时间。一、内部代码结构public class DelayQueue<E extends Delayed> extends AbstractQueue<E> implements BlockingQueue<E> {...原创 2020-01-19 22:54:30 · 253 阅读 · 0 评论 -
JAVA并发包(十三):PriorityBlockingQueue
PriorityBlockingQueue中文名可以叫做优先阻塞队列,它的内部是数组结构的最小堆,能够保证每次取出的都是队列中最小的节点(比较器返回的最小元素)。但是它在数组中不是有序,只保证数组的第一个节点是最小的,也就是说第一个优先权最高,首先会被取出。下图就是一个最小堆的示意图,它可以说是一个二叉树的结构,只需要保证父节点大于子节点,就满足最小堆的要求。然后就是从父节点开始,从上往下,从左...原创 2020-01-16 21:29:37 · 324 阅读 · 0 评论 -
JAVA并发包(十二):SynchronousQueue
SynchronousQueue也是阻塞队列中的一种,它用在线程池中可以让线程池动态调整线程数量,任务多它就创建多点线程去执行任务,任务少它就会把多余的线程释放掉。这在一定程度上提高了并发的吞吐量,但是需要注意的是系统资源是否承受的起线程的扩容。在代码层中,我们可以把SynchronousQueue说成是配对管道,管道中只有一种类型的它也是Collection...原创 2020-01-11 13:36:35 · 656 阅读 · 0 评论 -
JAVA并发包(十一):ArrayBlockingQueue
ArrayBlockingQueue 可以理解为环形数组的结构保存元素,里面只用了一把重入锁来控制出入队列的操作。另外,它虽然可以保证先进先出,但是入队列或者出队列有公平和非公平的选择,是通过重入锁实现的,默认是非公平的,那么入队列或者出队列不一定是先来的先请求到。一、代码结构从下面代码中可以看到ArrayBlockingQueue内部是维护了一个数据items,以及一个重入锁控制访问。 p...原创 2020-01-05 23:34:46 · 236 阅读 · 0 评论 -
JAVA并发包(十):LinkedBlockingQueue
LinkedBlockingQueue中文名叫链表阻塞队列,内部是链表结构,拥有先进先出的特性。说的阻塞的特性,是当队列满的时候插入元素会阻塞掉线程知道队列有空余位置,当队列为空的时候取出元素会阻塞直到队列有元素为止。LinkedBlockingQueue是BlockingQueue接口的实现类,我们首先来看看BlockingQueue接口。一、BlockingQueueBlockingQu...原创 2020-01-05 22:36:15 · 344 阅读 · 0 评论 -
JAVA并发包(九):Executors
Executors就是Executor多了一个s,但是它跟Executor没有依赖关系。它其实是一个工厂或者说是一个工具类,能够生产ExecutorService、ScheduleExecutorService、Callable、ThreadFactory实例。本篇文章暂时就讲解生产线程池的方法。一、单线程线程池从以下代码知道,单线程的线程池核心线程数和最大线程数都是1,所以不管什么情况它都是...原创 2020-01-05 20:29:16 · 372 阅读 · 0 评论 -
JAVA并发包(八):ExecutorCompletionService
ExecutorCompletionService它专门为那些需要返回的结果的任务设计的,它内部维护了一个阻塞队列,当任务执行完毕后会把结果放到这个队列里,调用poll就可以获取到这些结果。当调用take方法的时候,如果队列中没有结果,会阻塞等待。在之前介绍AbstractExecutorService类的invokeAny方法中提到了ExecutorCompletionService,invo...原创 2020-01-05 17:42:01 · 272 阅读 · 0 评论 -
JAVA并发包(七):ThreadPoolExecutor
从上篇文章中我们知道ThreadPoolExecutor继承于AbstractExecutorService,它是java并发的主要实现类,我们通常使用的三类线程池,都是通过ThreadPoolExecutor实现的。可以这样说,只要把ThreadPoolExecutor掌握了,那么对java线程池运作原理有了80%的理解。...原创 2020-01-05 16:30:15 · 311 阅读 · 0 评论 -
JAVA并发包(六):AbstractExecutorService
接下来我们开始研究激动人心的java并发的核心–线程池,并发包里的很多api都是服务于线程池的,像前面讲到AQS,重入锁,以及后面会讲解的阻塞队列等等,都可以在线程池的源码中看到。由于线程池设计到的api有多个,我这里就一步步来讲,先研究比较简单的AbstractExecutorService。一、接口关系图从以下关系图中可以看到,AbstractExecutorService作为抽象执行服务...原创 2019-12-09 23:33:21 · 493 阅读 · 0 评论 -
JAVA并发包(五):StampedLock
StampedLock是JDK8新增的API,是读写锁ReentrantReadWriteLock优化版,可以用来避免写饥饿。它使用版本戳和读写模式来控制并发访问,加锁会获得一个版本戳,然后解锁需要这个版本戳去匹配,匹配上才可以解锁。由于StampedLock的源码过于复杂,这里就不对源码做详细解读了,只是总结一下他的API特点以及使用场景。一、三种锁模式1. 悲观写锁这是普通的排他锁,只能...原创 2019-12-08 22:26:39 · 294 阅读 · 0 评论 -
JAVA并发包(三):ReentrantLock
ReentrantLock也叫做可重入锁,就是拿到锁的线程可以多次获得锁,体现在代码层面就是可以多次调用lock成功。一、基本结构下面是重入锁基本代码结构了,Sync继承了AQS(可以点击查看之前的博客解读),然后加锁和解锁是迪调用Sync的方法。所以只要理解了AQS,那么掌握重入锁就是水到渠成的事情了。public class ReentrantLock implements Lock, ...原创 2019-11-30 22:43:53 · 210 阅读 · 0 评论 -
JAVA并发包(二):LockSupport
LockSupport是挂起线程的一种实现方式,它不是同步锁,只是一个提供给同步锁调用,把当前线程挂起的协助类。它也能够单独使用,把某个线程挂起。一、方法介绍LockSupport的方法有以下几个,后面会一个个介绍1.挂起方法1.1 park()这个方法很简答,直接调用了UNSAFE类的原生方法,可以立即它会立刻把当前线程挂起。注意它是一个静态方法,直接通过类名引用就可以调用 ...原创 2019-11-30 20:07:44 · 281 阅读 · 0 评论 -
JAVA并发包(一):AbstractQueuedSynchronizer
一、简介AbstractQueuedSynchronizer俗称AQS,是一个抽象类,是重入锁,读写锁的基类。如果我们要全面学习java的并发锁,首先要掌握AQS的加锁机制。下面文章我将介绍AQS的结构,加锁和解锁方法。二、AQS的数据结构...原创 2019-11-26 22:48:34 · 342 阅读 · 0 评论 -
JAVA并发包(四):ReentrantReadWriteLock读写锁
一、概述ReentrantReadWriteLock就是可重入的读写锁,其继承AQS类,内部实现原理自然就是改造过的CLH锁CLH锁是有由Craig, Landin, and Hagersten这三个人发明的锁,取了三个人名字的首字母,所以叫 CLH Lock。CLH锁是一个自旋锁,能确保无饥饿性,提供先来先服务的公平性。CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只...原创 2019-07-07 10:13:00 · 336 阅读 · 0 评论
分享