随笔分类 - 并发编程
摘要:前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结果的影响。 按照官方的说法: 当一个变量被多个线程读取并且至少被一个线程写入时,如果读操作和写操作没
阅读全文
摘要:前言 楼主自1月14号就停更了,这段时间一直在看JVM,因此没有更新任何文章,但楼主觉得有必要总结一下之前学习并发的过程,因为这一次的总结其实就是下一次的开始。主要时总结一下并发的学习路线,因为在楼主的工作环境中,并不是每天都在编写高并发的程序。然而,即使是这样,我们也要知道并发的每个知识点,这样才
阅读全文
摘要:前言 每一次总结都意味着重新开始,同时也是为了更好的开始。ConcurrentHashMap 一直是我心中的痛。虽然不敢说完全读懂了,但也看了几个重要的方法,有不少我觉得比较重要的知识点。 然后呢,放一些楼主写的关于 ConcurrentHashMap 相关源码分析的文章链接: 1. "Concur
阅读全文
摘要:前言 ConcurrentHashMap 精华代码很多,前面分析了 helpTransfer 和 transfer 和 putVal 方法,今天来分析一下 addCount 方法,该方法会在 putVal 方法中调用。 该方法可以配合 size 方法一起查看,关于该方法,楼主也写了一篇文章分析过:
阅读全文
摘要:前言 这是一篇对 transfer 方法的拾遗,关于之前那篇文章的一些一笔带过,或者当时不知道的地方进行回顾。 疑点 1. 为什么将链表拆成两份的时候,0 在低位,1 在高位? 回顾一下 transfer 的相关代码: 关键看上面注释的代码,如果 runBit 是 0,那么就设置在低位节点,反之,如
阅读全文
摘要:前言 ConcurrentHashMap 是并发中的重中之重,也是最常用的数据结果,之前的文章中,我们介绍了 putVal 方法。 "并发编程之 ConcurrentHashMap(JDK 1.8) putVal 源码分析" 。其中分析了 initTable 方法和 putVal 方法,但也留下了一
阅读全文
摘要:前言 ConcurrentHashMap 鬼斧神工,并发添加元素时,如果 map 正在扩容,其他线程甚至于还会帮助扩容,也就是多线程扩容。就这一点,就可以写一篇文章好好讲讲。今天一起来看看。 源码分析 为什么帮助扩容? 在 putVal 方法中,如果发现线程当前 hash 冲突了,也就是当前 has
阅读全文
摘要:前言 RPC 服务中,每个服务的容量都是有限的,即资源有限,只能承受住给定的网络请求,所以,在设计 RPC 框架的时候,一定要考虑流量控制这个问题。而 Java 中,实现流量控制有很多中方式,今天说 2 种。 Semaphore 实现流控 代码: 这段代码和上面的类似,只是使用的 API 不同,这里
阅读全文
摘要:前言 如何中断一个线程,肯定不会使用 stop。而是使用 interrupt 方法。同时,我们知道,中断一个线程只是打个标志位。不会真的中断线程,但,如果线程是阻塞状态的呢? 而 Java 中,想要阻塞一个线程有很多种方式。 1. synchronized 2. Object.wait() 3. L
阅读全文
摘要:1. 前言 Java 中总的算起来有 8 种阻塞队列。 我们分析了: "并发编程之 SynchronousQueue 核心源码分析" "并发编程之 ConcurrentLinkedQueue 源码剖析" "并发编程之 LinkedBolckingQueue 源码剖析" 在 "并发编程 —— Sche
阅读全文
摘要:关于 Java 内存模型的类似思维导图。 如有错误,还请指正。
阅读全文
摘要:1. 前言 在前面的文章中,我们介绍了定时任务类 Timer ,他是 JDK 1.3 中出现的,位于 java.util 包下。而今天说的 的是在 JUC 包下,是 JDK1.5 新增的。 今天就来说说这个类。 2. API 介绍 该类内部结构和 还是有点类似的,也是 3 个类: :程序员使用的接口
阅读全文
摘要:前言 在平时的开发中,肯定需要使用定时任务,而 Java 1.3 版本提供了一个 java.util.Timer 定时任务类。今天一起来看看这个类。 1.API 介绍 Timer 相关的有 3 个类: Timer :面向程序员的API 都在这个类中。 TaskQuue: 存储任务。 TimerThr
阅读全文
摘要:1. 前言 在前面的文章 "并发编程之——写锁源码分析" 中,我们分析了 1.8 JUC 中读写锁中的 写锁的获取和释放过程 ,今天来分析一下读锁的获取和释放过程,读锁相比较写锁要稍微复杂一点,其中还有一点有争议的地方——锁降级。 今天就来解开迷雾。 2. 获取读锁 tryAcquireShared
阅读全文
摘要:1. 前言 当我们在 Java 中使用异步编程的时候,大部分时候,我们都会使用 Future,并且使用线程池的 submit 方法提交一个 Callable 对象。然后调用 Future 的 get 方法等待返回值。而 FutureTask 是 Future 的一个实现,也是我们今天的主角。 我们就
阅读全文
摘要:1. 前言 在并发编程中,异步回调的效率不言而喻,在业务开发中,如果由阻塞的任务需要执行,必然要使用异步线程。并且,如果我们想在异步执行之后,根据他的结果执行一些动作。 JDK 8 之前的 Future 只能解决上面需求的一半问题,即异步执行,返回一个 Future,需要程序员调用 get 方法等待
阅读全文
摘要:1.前言 Java 中的读写锁实现是 ReentrantReadWriteLock ,是一种锁分离策略。能有效提高读比写多的场景下的程序性能。 关于如何使用参见 "并发编程之 Java 三把锁" 。 由于读写锁较为复杂,故分为篇文章进行源码分析,今天先说较为简单的写锁。 2. 写锁介绍 不论是读锁还
阅读全文
摘要:前言 ConcurrentHashMap 博大精深,从他的 50 多个内部类就能看出来,似乎 JDK 的并发精髓都在里面了。但他依然拥有体验良好的 API 给我们使用,程序员根本感觉不到他内部的复杂。但,他内部的每一个方法都复杂无比,就连 size 方法,都挺复杂的。 今天就一起来看看这个 size
阅读全文
摘要:前言 ReentrantLock 提供了公平锁和非公平锁,只需要在构造方法中使用一个 参数即可。默认非公平锁。 今天从源码层面看看区别和具体实现。 1. 类 UML 图 内部有一个抽象类 ,继承了 AQS。 而公平锁的实现就是 ,非公平锁的实现就是 。 两把锁的区别在于 方法的实现。 2. 公平锁
阅读全文