并发编程
文章平均质量分 69
Java部落格
为了部落!!!
展开
-
JUC源码阅读(三)-CountDownLatch
一、CountDownLatch简介 CountDownLatch是一个基于AQS实现的同步辅助类,它允许一个或多个主任务线程一直等待,直到一组子任务线程完成。内部采用的公平锁和共享锁的机制实现。 由AQS的数据模型可推测,CountDownLatch应该是将一个或多个主任务线程放入到CLH等待队列中,等待所有子线程执行完后再获取锁执行下一步操作,而每个子任务执行完都会将计数-1,CLH等待队列中主任务需要不停的检测计数是否归零。二、CountDownLatch的核心方法1、CountDownL原创 2021-03-16 22:51:51 · 73 阅读 · 0 评论 -
JUC源码阅读(二)-ReentrantLock
一、ReentrantLock简介ReentrantLock基于AQS实现的可重入锁,是一个跟synchronized具有相同行为和语义的持有锁来访问方法和语句的互斥锁,但是reentrant还拥有被扩展的能力,可以有公平锁和非公平锁的不同实现,只要在构造它的时候传入不同的布尔值,就可以实现。public ReentrantLock(boolean fair) { // 默认是非公平锁 sync = fair ? new FairSync() : new NonfairSync();}二、Re原创 2021-03-16 21:25:29 · 82 阅读 · 0 评论 -
JUC源码阅读(一)-AQS
一、AQS简介AbstractQueuedSynchronizer,简称AQS,JUC并发包中常用的ReentrantLock, CountDownLatch等都依赖AQS。子类通过继承AQS并实现它的抽象方法来管理同步状态,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作,但是通过AQS实现的功能却是不同的。二、AQS数据结构下图就是AQS的数据模型:接下来再来看看AbstractQueuedSynchronizer的成员变量// CLH队列头结点private t原创 2021-03-14 12:22:26 · 210 阅读 · 0 评论 -
HashMap、ConcurrentHashMap核心要点
一、HashMap1、JDK7数组+单向链表头插法存在死循环bug2、JDK8数组+单向链表+红黑树尾插法3、HashMap头插法死循环问题可以参考如下文章:《HashMap头插法为什么会出现死循环 产生循环链表的影响是什么》二、ConcurrentHashMap1、JDK7分段锁,每个Segment有独立的锁,Segment实现了ReentrantLock,也就带有锁的功能。1、分为16个Segment(相当于HashTable)2、对每一个小的Segment加原创 2021-03-13 15:28:14 · 97 阅读 · 0 评论 -
ThreadPoolExecutor源码阅读
一、Executors创建线程池的工厂方法Executors是线程池的工具类,它提供了四种创建线程池的工厂方法:newFixedThreadPool:该方法返回一个固定数量的线程池,线程数不变,当有一个任务提交时,若线程池中空闲,则立即执行,若没有,则会被暂缓在一个任务队列中,等待有空闲的线程去执行;newSingleThreadExecutor: 创建一个线程的线程池,若空闲则执行,若没有空闲线程则暂缓在任务队列中;newCachedThreadPool:返回一个可根据实际情况调整线程个数的线原创 2021-03-07 20:42:52 · 99 阅读 · 0 评论 -
线程私有变量—ThreadLocal
一、ThreadLocal数据结构Thread类中有个变量threadLocals,这个类型为ThreadLocal中的一个内部类ThreadLocalMap,这个类没有实现map接口,就是一个普通的Java类,但是实现的类似map的功能。Thread中的成员变量threadLocals: /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */原创 2021-02-28 17:52:44 · 689 阅读 · 1 评论 -
高性能内存队列—Disruptor
一、Disruptor介绍1、Disruptor特点:基于数组实现的,数组相比链表,查询更快,但是新增/修改操作较慢,而Disruptor的数组是环形数组,是定长的数组,无需扩容,直接覆盖旧数据,所以相比ConcurrentLinkedQueue,性能更好。对比下也是基于数组实现的HashMap,每次扩容耗时较长;基于CAS无锁化,高并发,使用环形Buffer,直接覆盖(不用清除)旧的数据,降低GC频率;实现了基于事件的生产者消费者模式(观察者模式);2、Disruptor的使用定义原创 2021-02-28 17:04:40 · 592 阅读 · 0 评论 -
浅谈JDK 9—Flow
一、响应式编程JDK 9 Flow 是JDK对Reactive Stream (响应式流/反应流) 的实现,Reactive Stream是一套基于发布/订阅模式的数据处理规范。响应式流从2013年开始,作为提供非阻塞背压的异步流处理标准的倡议。 它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者,而不需要发布者阻塞,或订阅者需要有无限制的缓冲区或丢弃。更确切地说,Reactive流目的是“找到最小的一组接口,方法和协议,用来描述必要的操作和实体以实现这样的目标:以非阻塞背压方式实现数据的异步原创 2021-02-18 16:45:47 · 1433 阅读 · 0 评论 -
浅谈JDK异步编程演进史
一、JDK 5以前—Runnable缺点:异步线程没有返回值,并且无法抛出返回结果的异常。二、JDK 5—CallableCallable功能更强大一些,被线程执行后,可以通过Future拿到返回值。缺点:Future是它没有提供通知的机制,我们无法得知Future什么时候完成。要么使用阻塞,在future.get()的地方等待future返回的结果,这时又变成同步操作。要么使用isDone()轮询地判断Future是否完成,这样会耗费CPU的资源。三、JDK 7—Fork/joi原创 2021-02-18 16:44:48 · 145 阅读 · 0 评论 -
浅谈JDK 8—Stream
一、Stream是高级的集合迭代器流和集合的区别:1、集合是一种内存数据结果,必须先计算出来才能放到集合中,而流是按需计算;2、流只能遍历一次,如果需要再次遍历,必须重新获取数据源,流只能被消费一次,而集合因为是内存中的一个确定数据结构,所以可以遍历多次;3、流的迭代在内部完成,而集合必须在外部通过代码显式迭代。 4、流用于描述对于数据的计算,集合主要是为了存储和访问数据。二、Stream API 函数式编程1、声明式编程:专注于”做什么”而不是”zhi如何去做”。在更dao高层面zhua原创 2021-02-18 16:43:04 · 97 阅读 · 1 评论