并发编程
坯子蔡
永远怀着一颗学习的心去行走
展开
-
42 - 案例分析(四):高性能数据库连接池HiKariCP
案例分析(四):高性能数据库连接池HiKariCP1. 什么是数据库连接池2. FastList 解决了哪些性能问题3. ConcurrentBag 解决了哪些性能问题4. 总结 实际工作中,我们总会难免和数据库打交道;只要和数据库打交道,就免不了使用数据库连接池。业界知名的数据库连接池有不少,例如 c3p0、DBCP、Tomcat JDBC Connection Pool、Druid 等,不过最近最火的是 HiKariCP。 HiKariCP 号称是业界跑得最快的数据库连接池,这两年发展得顺原创 2020-07-20 00:24:26 · 758 阅读 · 0 评论 -
41 - 案例分析(三):高性能队列Disruptor
案例分析(三):高性能队列Disruptor1. RingBuffer 如何提升性能2. 如何避免“伪共享”3. Disruptor 中的无锁算法4. 总结 我们在《24 - 并发容器》介绍过 Java SDK 提供了 2 个有界队列:ArrayBlockingQueue 和 LinkedBlockingQueue,它们都是基于 ReentrantLock 实现的,在高并发场景下,锁的效率并不高,那有没有更好的替代品呢?有,今天我们就介绍一种性能更高的有界队列:Disruptor。 Disru原创 2020-07-19 23:29:37 · 374 阅读 · 0 评论 -
40 - 案例分析(二):高性能网络应用框架Netty
案例分析(二):高性能网络应用框架Netty1. 网络编程性能的瓶颈2. Reactor 模式3. Netty 中的线程模型4. 用 Netty 实现 Echo 程序服务端.5. 总结 Netty 是一个高性能网络应用框架,应用非常普遍,目前在 Java 领域里,Netty 基本上成为网络程序的标配了。Netty 框架功能丰富,也非常复杂,今天我们主要分析 Netty 框架中的线程模型,而线程模型直接影响着网络程序的性能。 在介绍 Netty 的线程模型之前,我们首先需要把问题搞清楚,了解网络原创 2020-07-19 22:31:54 · 253 阅读 · 0 评论 -
39 - 案例分析(一):高性能限流器Guava RateLimiter
案例分析(一):高性能限流器Guava RateLimiter1. 经典限流算法:令牌桶算法2. Guava 如何实现令牌桶算法3. 总结 从今天开始,我们就进入案例分析模块了。 这个模块我们将分析四个经典的开源框架,看看它们是如何处理并发问题的,通过这四个案例的学习,相信你会对如何解决并发问题有个更深入的认识。 首先我们来看看 Guava RateLimiter 是如何解决高并发场景下的限流问题的。Guava 是 Google 开源的 Java 类库,提供了一个工具类 RateLimiter原创 2020-07-19 18:41:27 · 416 阅读 · 0 评论 -
38 - 生产者-消费者模式:用流水线思想提高效率
生产者-消费者模式:用流水线思想提高效率1. 生产者 - 消费者模式的优点2. 支持批量执行以提升性能3. 支持分阶段提交以提升性能4. 总结 前面我们在《Worker Thread模式:工作线程池》中讲到,Worker Thread 模式类比的是工厂里车间工人的工作模式。但其实在现实世界,工厂里还有一种流水线的工作模式,类比到编程领域,就是生产者 - 消费者模式。 生产者 - 消费者模式在编程领域的应用也非常广泛,前面我们曾经提到,Java 线程池本质上就是用生产者 - 消费者模式实现的,所原创 2020-07-19 17:32:45 · 445 阅读 · 0 评论 -
37 - 两阶段终止模式:优雅地终止线程
两阶段终止模式:优雅地终止线程1. 如何理解两阶段终止模式2. 用两阶段终止模式终止监控操作3. 如何优雅地终止线程池4. 总结 前面两篇文章我们讲述的内容,从纯技术的角度看,都是启动多线程去执行一个异步任务。既启动,那又该如何终止呢?今天咱们就从技术的角度聊聊如何优雅地终止线程,正所谓有始有终。 在前面曾讲过:线程执行完或者出现异常就会进入终止状态。这样看,终止一个线程看上去很简单啊!一个线程执行完自己的任务,自己进入终止状态,这的确很简单。不过我们今天谈到的“优雅地终止线程”,不是自己终止原创 2020-07-19 16:13:42 · 171 阅读 · 0 评论 -
36 - Worker Thread模式:工作线程池
Worker Thread模式:工作线程池1. Worker Thread 模式及其实现2.1 正确地创建线程池2.2 避免线程死锁3. 总结 在上一篇文章中,我们介绍了一种最简单的分工模式——Thread-Per-Message 模式,对应到现实世界,其实就是委托代办。这种分工模式如果用 Java Thread 实现,频繁地创建、销毁线程非常影响性能,同时无限制地创建线程还可能导致 OOM,所以在 Java 领域使用场景就受限了。 要想有效避免线程的频繁创建、销毁以及 OOM 问题,就不得不原创 2020-07-16 20:59:20 · 432 阅读 · 0 评论 -
35 - Thread-Per-Message模式:委托他人代办
Thread-Per-Message模式:委托他人代办1. 理解 Thread-Per-Message 模式2. 用 Thread 实现 Thread-Per-Message 模式3. 总结 我们曾经把并发编程领域的问题总结为三个核心问题:分工、同步和互斥。其中,同步和互斥相关问题更多地源自微观,而分工问题则是源自宏观。我们解决问题,往往都是从宏观入手,在编程领域,软件的设计过程也是先从概要设计开始,而后才进行详细设计。同样,解决并发编程问题,首要问题也是解决宏观的分工问题。 并发编程领域里,解决分原创 2020-07-16 20:17:47 · 140 阅读 · 0 评论 -
34 - Balking模式:快速放弃的阻止模式
Balking模式:快速放弃的阻止模式1. Balking 模式的经典实现2. 用 volatile 实现 Balking 模式3. 总结 上一篇《33 - Guarded Suspension模式 等待唤醒机制的规范》文章中,我们提到可以用“多线程版本的 if”来理解 Guarded Suspension 模式,不同于单线程中的 if,这个“多线程版本的 if”是需要等待的,而且还很执着,必须要等到条件为真。但很显然这个世界,不是所有场景都需要这么执着,有时候我们还需要快速放弃。 需要快速放弃的一原创 2020-07-16 19:11:53 · 166 阅读 · 0 评论 -
33 - Guarded Suspension模式 等待唤醒机制的规范
Guarded Suspension模式 等待唤醒机制的规范1. Guarded Suspension 模式2. 扩展 Guarded Suspension 模式3. Dubbo 源码分析4. 总结 前不久,同事小灰工作中遇到一个问题,他开发了一个 Web 项目:Web 版的文件浏览器,通过它用户可以在浏览器里查看服务器上的目录和文件。这个项目依赖运维部门提供的文件浏览服务,而这个文件浏览服务只支持消息队列(MQ)方式接入。消息队列在互联网大厂中用的非常多,主要用作流量削峰和系统解耦。在这种接入方式中,原创 2020-07-15 23:53:54 · 199 阅读 · 0 评论 -
32 - ThreadLocal 线程本地存储模式 没有共享就没有伤害
ThreadLocal 线程本地存储模式 没有供销就没有伤害1. ThreadLocal 的使用方法2. ThreadLocal 工作原理3. ThreadLocal 与内存泄露3. InheritableThreadLocal 与继承性5. 总结 民国年间某山东省主席参加某大学校庆演讲,在篮球场看到十来个人穿着裤衩抢一个球,观之实在不雅,于是怒斥学校的总务处长贪污,并且发话:“多买几个球,一人发一个,省得你争我抢!”小时候听到这个段子只是觉得好玩,今天再来看,却别有一番滋味。为什么呢?因为其间蕴藏着解原创 2020-07-12 15:10:10 · 223 阅读 · 0 评论 -
31 - Copy-on-Write模式 不是延迟策略的写时复制
Copy-on-Write模式 不是延迟策略的写时复制1. Copy-on-Write 模式的应用领域2. 真实案例3. 总结 在上一篇文章中我们讲到 Java 里 String 这个类在实现 replace() 方法的时候,并没有更改原字符串里面 value[]数组的内容,而是创建了一个新字符串,这种方法在解决不可变对象的修改问题时经常用到。如果你深入地思考这个方法,你会发现它本质上是一种 Copy-on-Write 方法。所谓 Copy-on-Write,经常被缩写为 COW 或者 CoW,顾名思义原创 2020-07-12 10:30:56 · 206 阅读 · 0 评论 -
30 - Immutability模式:利用不变性解决并发问题
Immutability模式:利用不变性解决并发问题1. 快速实现具备不可变性的类2. 利用享元模式避免创建重复对象3. 使用 Immutability 模式的注意事项4. 总结 我们曾经说过,“多个线程同时读写同一共享变量存在并发问题”,这里的必要条件之一是读写,如果只有读,而没有写,是没有并发问题的。 解决并发问题,其实最简单的办法就是让共享变量只有读操作,而没有写操作。这个办法如此重要,以至于被上升到了一种解决并发问题的设计模式:不变性(Immutability)模式。所谓不变性,简单来讲,就原创 2020-07-09 20:59:42 · 279 阅读 · 1 评论 -
29 - Fork/Join 分治任务模型
Fork/Join 分治任务模型1. 分治任务模型2. Fork/Join 的使用3. ForkJoinPool 工作原理4. 模拟 MapReduce 统计单词数量5. 总结 前面几篇文章我们介绍了线程池、Future、CompletableFuture 和 CompletionService,仔细观察你会发现这些工具类都是在帮助我们站在任务的视角来解决并发问题,而不是让我们纠缠在线程之间如何协作的细节上(比如线程之间如何实现等待、通知等)。对于简单的并行任务,你可以通过“线程池 +Future”的方原创 2020-07-09 19:43:03 · 922 阅读 · 0 评论 -
28 - CompletionService 批量执行异步任务
CompletionService 批量执行异步任务1. 询价系统1.1 ThreadPoolExecutor + Future1.2 ThreadPoolExecutor + Queue1.3 利用 CompletionService 实现询价系统2. 理解 CompletionService 接口2.1 创建 CompletionService 接口2.2 CompletionService 方法2.3 利用 CompletionService 实现 Dubbo 中的 Forking Cluster3.原创 2020-07-05 23:51:58 · 271 阅读 · 0 评论 -
27- CompletableFuture 异步编程
CompletableFuture 异步编程1. CompletableFuture 的核心优势1.1 CompletableFuture 使用1.2 创建 CompletableFuture 对象1.3 理解 CompletionStage 接口1.3.1 描述串形关系1.3.2 描述 AND 汇聚关系1.3.3 描述 OR 汇聚关系1.3.4 异常处理 前面我们不止一次提到,用多线程优化性能,其实不过就是将串行操作变成并行操作。如果仔细观察,你还会发现在串行转换成并行的过程中,一定会涉及到异步化,例原创 2020-07-05 21:22:17 · 158 阅读 · 0 评论 -
26 - Future 获取异步任务的结果
Future 获取异步任务的结果1. 如何获取任务的执行结果1.1 ThreadPoolExecutor.submit1.2 FutureTask 工具类2. 实现最优的“烧水泡茶”程序3. 总结 在上一篇文章《25 - ThreadPoolExecutor 线程池》中,我们详细介绍了如何创建正确的线程池,也粗略了讲了一下如何启动线程池,execute() 和 submit() 都是用来执行线程池任务的,它们最主要的区别是,submit() 方法可以接收线程池执行的返回值,而 execute() 不能接原创 2020-07-05 10:42:25 · 3815 阅读 · 0 评论 -
25 - ThreadPoolExecutor 线程池
ThreadPoolExecutor 线程池1. 线程池原理2. ThreadPoolExecutor2.1 核心参数2.2 执行流程2.3 启动方式2.4 拒绝策略2.5 自定义拒绝策略2.6 扩展3. 如何设置线程池的大小4. 四种线程池4.1 newCachedThreadPool4.2 newFixedThreadPool4.3 newScheduledThreadPool4.4 newSingleThreadExecutor 虽然在 Java 语言中创建线程看上去就像创建一个对象一样简单,只原创 2020-07-04 23:19:20 · 179 阅读 · 0 评论 -
24 - 并发容器
并发容器1. 同步容器及其注意事项1.1 同步容器1.2 注意事项2. 并发容器及注意事项2.1 List2.2 Map2.3 Set2.4 Queue Java 并发包有很大一部分内容都是关于并发容器的,因此学习和搞懂这部分的内容很有必要。 Java 1.5 之前提供的同步容器虽然也能保证线程安全,但是性能很差,而 Java 1.5 版本之后提供的并发容器在性能方面则做了很多优化,并且容器的类型也更加丰富了。下面我们就对比二者来学习这部分的内容。 1. 同步容器及其注意事项1.1 同步容器原创 2020-07-04 22:47:35 · 133 阅读 · 0 评论 -
23 - Semaphore 信号量
Semaphore 信号量1. Semaphore 模型2. Semaphore 使用3. 源码分析3.1 类结果3.2 acquire3.3 release4. 总结 本篇介绍第三个并发工具类 Semaphore,Semaphore 可以理解为信号量,用于控制资源能够被并发访问的线程数量,以保证多个线程能够合理的使用特定资源。1. Semaphore 模型 信号量模型还是很简单的,可以简单概括为:一个计数器,一个等待队列,三个方法。在信号量模型里,计数器和等待队列对外是透明的,所以只能通过信号量原创 2020-07-04 21:06:14 · 154 阅读 · 0 评论 -
22 - CyclicBarrier 一组线程之间相互等待
CyclicBarrier 一组线程之间相互等待1. CyclicBarrier 的使用1.1 主要方法1.2 使用举例1.3 与 CountDownLatch 比较2. 源码分析2.1 类结构2.2 构造器2.3 await3. 对账系统4. 总结1. CyclicBarrier 的使用 CyclicBarrier 要做的事情是让一组线程未到达一个屏障(条件)时被阻塞,直到最后一个线程到达屏障(条件)时,屏障(条件)才会开门,所有被屏障拦截的线程一起执行。 1.1 主要方法CyclicBar原创 2020-07-04 18:38:09 · 260 阅读 · 0 评论 -
21 - CountDownLatch 让线程等待其他线程完成
CountDownLatch 让线程等待其他线程完成1. CountDownLatch 使用1.1 使用背景1.2 利用并行优化1.3 用 CountDownLatch 实现线程等待2. 源码分析2.1 类结构2.2 await2.3 countDown3. 总结 并发编程中常遇到这种情况,一个线程需要等待另外多个线程执行后再执行。遇到这种情况你一般怎么做呢?今天就介绍一种 JDk 提供的解决方案来优雅的解决这一问题,那就是倒计时器 CountDownLatch。1. CountDownLatch 使原创 2020-07-04 12:20:47 · 400 阅读 · 0 评论 -
20 - Lock-Condition 的等待通知
Lock-Condition 的等待通知1. condition 的使用1.2 等待方法1.2 唤醒方法1.3 使用举例2. condition 与 wait / notify3. 源码分析3.1 条件队列3.2 await3.3 signal3.4 过程总结4. 生产者消费者5. 总结 在上一篇文章中,我们讲到 Java SDK 并发包里的 Lock 有别于 synchronized 隐式锁的三个特性:能够响应中断、支持超时和非阻塞地获取锁。那今天我们接着再来详细聊聊 Java SDK 并发包里的 C原创 2020-07-03 20:23:34 · 117 阅读 · 0 评论 -
19 - StampedLock 比读写锁更快的锁
StampedLock 比读写锁更快的锁1. 为什么引入 StamedLock1.1 读写锁的问题1.2 StamedLock2. 三种锁模式2.1 写锁 writeLock2.2 悲观读锁 readLock2.3 乐观读 OptimisticReading3. 使用注意事项4. 源码分析4.1 锁状态4.2 属性4.2.1 锁状态相关属性4.2.2 节点4.3 写锁的获取与释放4.4 悲观锁的获取与释放4.5 乐观读的获取5. 总结 在上一篇《18 - ReentrantReadWriteLock 读原创 2020-07-01 20:35:59 · 284 阅读 · 0 评论 -
18 - ReentrantReadWriteLock 读写锁
ReentrantReadWriteLock 读写锁1. 读写锁概念1.1 为什么需要读写锁1.2 读写锁原则1.3 读写锁的应用1.4 读写锁的降级2. 源码分析2.1 类结构2.2 记录读写锁的状态2.3 记录获取锁的线程2.4 读锁获取2.4.1 tryAcquireShared 尝试获取读锁2.4.1.1 readerShouldBlock2.4.1.2 fullTryAcquireShared2.4.1.3 doAcquireShared2.4.1.4 setHeadAndPropagate2.5原创 2020-07-01 15:46:28 · 218 阅读 · 0 评论 -
17 - ReentrantLock 公平锁与非公平锁
ReentrantLock 公平锁与非公平锁1. 为什么需要公平锁2. 公平锁与非公平锁的实现2.1 类结构2.2 构造函数2.3 获取锁2.3.1 lock()方法源码2.3.2 tryAcquire()方法源码2.3.3 分析实现总结2.4 公平锁 VS 非公平锁3 总结 在上篇文章《16 - ReentrantLock 可重入锁》中我们介绍过,ReentrantLock 这个类有两个构造函数,一个是无参构造函数,一个是传入 fair 参数的构造函数。fair 参数代表的是锁的公平策略,如果传入 t原创 2020-06-27 15:45:29 · 273 阅读 · 0 评论 -
16 - ReentrantLock 可重入锁
ReentrantLock 可重入锁1. ReentrantLock 概念1.1 背景1.2 保证可见性1.3 可重入锁1.4 公平锁与非公平锁2. 源码分析2.1 类结构2.2 获取锁2.3 释放锁2.4 如何实现重入3. 总结1. ReentrantLock 概念1.1 背景 Java 语言本身提供的 synchronized 也是管程的一种实现,既然 Java 从语言层面已经实现了管程了,那为什么还要在 SDK 里提供另外一种实现呢?难道 Java 标准委员会还能同意“重复造轮子”的方案?很显原创 2020-06-27 11:55:11 · 158 阅读 · 0 评论 -
15 - AQS 源码分析
AQS 源码分析1. AQS 概念1.1 AQS 原理1.2 AQS 资源共享方式2. AQS 源码分析2.1 AQS 类结构2.1.1 属性2.1.2 方法2.1.3 内部类2.2 同步队列2.2.1 队列结构2.2.2 节点类2.2.3 入队操作2.3 获取锁2.4 释放锁2.5 回顾整个历程3. 总结1. AQS 概念1.1 AQS 原理 AbstractQueuedSynchronizer 类如其名,抽象的队列式的同步器,AQS 定义了一套多线程访问 共享资源的同步器框架,许多同步类实现都依原创 2020-06-26 00:44:36 · 279 阅读 · 0 评论 -
14 - CAS 无锁工具类的典范
CAS 无锁工具类的典范1. CAS 介绍2. CAS 解决原子性问题3. CAS 原理4. CAS 问题4.1 ABA 问题4.2 自旋时间过长4.3 只能保证一个共享变量的原子操作5. Java 中的原子操作类5.1 基本数据类型的原子操作类5.2 数组类型的原子操作类5.3 引用类型的原子操作类5.4 字段类型的原子操作类5.5 原子化的累加器6 总结 并发编程,为了保证数据的安全,需要满足三个特性:原子性、可见性、有序性。Java 中可以通过锁和 CAS 的方式来实现原子操作。 在《13 -原创 2020-06-25 17:19:16 · 278 阅读 · 0 评论 -
13 - synchronized 同步互斥锁
并发编程之 Synchronized 关键字:解决原子性1. Synchronized 使用1.1 线程安全问题1.2 Synchronized 概念1.3 Synchronized 的作用范围2. Synchronized 原理2.1 同步代码块2.2 同步方法2.3 Monitor2.3.1 Monitor 是什么2.3.2 Monitor 如何实现线程同步3. 解决三大问题:原子性、可见性和有序性3.1 保证原子性3.2 保证有序性3.3 保证可见性1. Synchronized 使用1.1 线程原创 2020-06-25 15:07:20 · 731 阅读 · 0 评论 -
12 - volatile 解决可见行和有序性
并发编程之 volatile 关键字 - 解决可见行和有序性1. 原理1.1 保证有序性原理1.2 保证可见行原理1.3 查看字节码1. 原理 Java 语言提供了一种稍弱的同步机制,即 volatile 关键字,该关键字可以保证修饰的变量更新操作能够通知到其他线程,并且保证变量执行前后的顺序执行,即能够解决《01-可见性、原子性和有序性问题:并发编程 Bug 的源头》中提到的并发编程 Bug 源头的两个因素:可见行和有序性。1.1 保证有序性原理 JMM 通过插入内存屏障指令来禁止特定类型的重原创 2020-06-23 19:05:56 · 240 阅读 · 0 评论 -
11 - 如何用面向对象思想写好并发程序
如何用面向对象思想写好并发程序1. 封装共享变量2. 识别共享变量间的约束条件3. 制定并发访问策略4. 总结5. 思考 面向对象思想与并发编程有关系吗?本来是没关系的,它们分属两个不同的领域,但是在 Java 语言里,这两个领域被无情地融合在一起了,好在融合的效果还是不错的:在 Java 语言里,面向对象思想能够让并发编程变得更简单。 那如何才能用面向对象思想写好并发程序呢?我觉得你可以从封装共享变量、识别共享变量间的约束条件和制定并发访问策略这三个方面下手。 1. 封装共享变量 并发程原创 2020-05-29 10:55:07 · 302 阅读 · 0 评论 -
10 - 为什么局部变量是线程安全的
为什么局部变量是线程安全的1. 方法是如何被执行的2. 局部变量存哪里3. 调用栈与线程4. 线程封闭5. 思考 我们一遍一遍重复再重复地讲到,多个线程同时访问共享变量的时候,会导致并发问题。那在 Java 语言里,是不是所有变量都是共享变量呢?工作中我发现不少同学会给方法里面的局部变量设置同步,显然这些同学并没有把共享变量搞清楚。那 Java 方法里面的局部变量是否存在并发问题呢?下面我们就先结合一个例子剖析下这个问题。 比如,下面代码里的 fibonacci() 这个方法,会根据传入的参数原创 2020-05-28 20:11:01 · 431 阅读 · 0 评论 -
08 - 安全性、活跃性以及性能问题
安全性、活跃性以及性能问题1. 安全性问题1.1 线程安全1.2 数据竞争1.3 竞争条件1.4 解决方案 - 锁2. 活跃性问题2.1 死锁2.2 活锁2.3 饥饿3. 性能问题4. 总结 并发编程中我们需要注意的问题有很多,很庆幸前人已经帮我们总结过了,主要有三个方面,分别是:安全性问题、活跃性问题和性能问题。下面我就来一一介绍这些问题。 1. 安全性问题1.1 线程安全 相信你一定听说过类似这样的描述:这个方法不是线程安全的,这个类不是线程安全的,等等。 那什么是线程安全呢?其实本原创 2020-05-28 19:41:55 · 165 阅读 · 0 评论 -
05 - 线程死锁了,怎么办?
目录从现实世界寻找答案没有免费的午餐破坏占有且等待条件破坏不可抢占条件破坏循环等待条件总结在上一篇文章中,我们用 Account.class 作为互斥锁,来解决银行间的转账问题,虽然这个方案不存在并发问题,但是所有的账户的转账都是串行的,这种转账串行化性能太差。这里我们尝试把性能提升一下。从现实世界寻找答案现实世界里,账户转账操作是支持并发的,而且绝对是真...原创 2019-04-16 19:02:10 · 437 阅读 · 0 评论 -
06 - 用等待 - 通知机制优化循环等待
目录完美的就医流程用 synchronized 实现等待 - 通知机制小试牛刀:一个更好地资源分配器尽量使用 notifyAll()总结思考在上篇文章中我们已经知道,在破坏占有且等待条件的时候,如果转出和转入账本不满足同时在文件架上时,就用死循环的方式来循环等待,核心代码如下:// 一次性申请转出账户和转入账户,直到成功while(!actr.apply(thi...原创 2019-04-16 19:01:41 · 238 阅读 · 1 评论 -
03 - 互斥锁(上):解决原子性问题
我们知道,一个或多个操作在CPU执行的过程中不被中断的特性,称为“原子性“。理解这个特性有助于分析并发编程Bug出现的原因,例如利用它可以分析出long型在32位机器上读写可能出现的诡异Bug,明明已经把变量成功写入内存,从新读出来确不是自己写入的。原子性问题该如何解决我们知道,原子性问题的源头是线程切换,在同一时刻只有一个线程执行,我们称为互斥。如果我们能保证对共享变量的修改是...原创 2019-04-16 19:02:40 · 465 阅读 · 0 评论 -
02 - Java内存模型:看 Java 如何解决可见性和有序性问题
目录什么是Java内存模型使用volatile关键字Happens-Before规则1. 程序的顺序性规则2. volatile变量规则3. 传递性4. 管程中锁的规则5. 线程start() 规则6. 线程join() 规则总结思考什么是Java内存模型上篇文章已知,导致可见性的原因是缓存,导致有序性的原因是编译优化,那解决可见性、有序性最直接...原创 2019-04-16 19:02:54 · 283 阅读 · 0 评论 -
04 - 互斥锁(下):用一把锁保护多个资源
目录保护没有关联关系的多个资源保护有关联关系的多个资源总结我们已经知道受保护资源和锁之间合理的关联关系应该是N:1 的关系,也就是说可以用一把锁保护多个资源,但是不能用多把锁保护一个资源,今天我们就来聊聊如何保护多个资源。当我们要保护多个资源时,首先要区分这些资源是否存在关联保护没有关联关系的多个资源在编程领域,对于没有关联关系的资源,是很容易解决的...原创 2019-04-16 19:04:25 · 423 阅读 · 0 评论 -
07-管程:并发编程的万能钥匙
目录什么是管程管程模型解决互斥问题解决线程间的同步问题代码实现wait() 的正确姿势总结思考管程是一种可以很方便解决并发问题的核心技术,Java 语言在 1.5 之前,提供的唯一的并发原语就是管程,而且 1.5 之后提供的 SDK并发包,也是以管程技术为基础的。可以说,管程就是一把解决并发问题的万能钥匙。什么是管程所谓管程,指的是管理共享变量以及...原创 2019-04-16 19:01:18 · 1021 阅读 · 1 评论