java并发编程实战《三》互斥锁(上)
互斥锁(上):解决原子性问题
原子性问题的源头是线程切换,操作系统做线程切换是依赖 CPU 中断的,所以禁止 CPU 发生中断就能够禁止线程切换。
在早期单核 CPU 时代,这个方案的确是可行的,而且也有很多应用案例,但是并不适合多核场景。
这里我们以 32 位 CPU 上执行 long 型变量的写操作为例来说明这个问题,long 型变量是 64 位,在 32 位 CPU 上执行写操作会被拆分成两次写操作

1 class X {
2 // 修饰非静态方法
3 synchronized void foo() {
4 // 临界区
5 }
6 // 修饰静态方法
7 synchronized static void bar() {
8 // 临界区
9 }
10 // 修饰代码块
11 Object obj = new Object();
12 void method() {
13 synchronized(obj) {
14 // 临界区
15 }
16 }
17 }
可能你会奇怪,加锁 lock() 和解锁 unlock() 在哪里呢?其实这两个操作都是有的,只是这两个操作是被 Java 默默加上的,Java 编译器会在 synchronized 修饰的方法或代码块前后自动加上加锁 lock() 和解锁 unlock(),这样做的好处就是加锁 lock() 和解锁 unlock() 一定是成对出现的,毕竟忘记解锁 unlock() 可是个致命的 Bug(意味着其他线程只能死等下去了)。
当修饰静态方法的时候,锁定的是当前类的 Class 对象,在上面的例子中就是 Class X;
当修饰非静态方法的时候,锁定的是当前实例对象 this。
锁和受保护资源的关系
java并发编程实战《三》互斥锁(上)的更多相关文章
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- 《Java并发编程实战》笔记-锁与原子变量性能比较
如果线程本地的计算量较少,那么在锁和原子变量上的竞争将非常激烈.如果线程本地的计算量较多,那么在锁和原子变量上的竞争会降低,因为在线程中访问锁和原子变量的频率将降低. 在高度竞争的情况下,锁的性能将超 ...
- Java并发编程实战 04死锁了怎么办?
Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...
- Java并发编程实战 05等待-通知机制和活跃性问题
Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- 【Java并发编程实战】-----“J.U.C”:Semaphore
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
随机推荐
- read函数
ssize_t read(int fildes, void *buf, size_t nbyte); 返回值: > 0: 实际读到的字节数 = 0: 读完数据(读文件, 管道, socket末尾 ...
- 深入探索Spring Data JPA, 从Repository 到 Specifications 和 Querydsl
数据访问层,所谓的CRUD是后端程序员的必修课程,Spring Data JPA 可以让我们来简化CRUD过程,本文由简入深,从JPA的基本用法,到各种高级用法. Repository Spring ...
- .NET 5.0正式发布,功能特性介绍(翻译)
本文由葡萄城技术团队翻译并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 我们很高兴今天.NET5.0正式发布.这是一个重要的版本-其中也包括了C# ...
- 数论总结——更新ing
数论还是有很多没学完 只是小小的总结 一.同余定理 1.反身性:\(a\equiv a (mod m)\) 2.对称性:若\(a\equiv b(mod m)\),则\(b\equiv a (mod ...
- 弹性盒模型flex-grow的计算
flex-grow属性是弹性盒布局模块的子属性. 它定义了弹性项目在必要时增长的能力. 它接受作为比例的无单位值. 它决定了项目应在伸缩容器内部占用多少可用空间. 例如,如果所有项目的flex-gro ...
- CSS3之animation属性
CSS中的animation属性可用于为许多其他CSS属性设置动画,例如颜色,背景色,高度或宽度. 每个动画都需要使用@keyframes这种at-rule语句定义,然后使用animation属性来调 ...
- [MIT6.006] 18. Speeding up Dijkstra 加速Dijkstra算法
在之前的课我们讲过了Dijkstra算法,先回顾下,如下图: 那么如果加速DIjkstra算法寻找最短路径呢?这节课上讲师讲了两种方法:双向搜索(Bi-Directional Search)和目标方向 ...
- 使用配置文件方式记录Python程序日志
开发者可以通过三种方式配置日志记录: 调用配置方法的Python代码显式创建记录器.处理程序和格式化程序. 创建日志配置文件并使用fileConfig() 函数读取. 创建配置信息字典并将其传递给di ...
- waf 引擎 云原生平台tproxy 实现调研
了解了基本 云原生架构,不清楚的查看之前的文章:https://www.cnblogs.com/codestack/p/13914134.html 现在来看看云原生平台tproxy waf引擎串联实现 ...
- pandas.DataFarme内置的绘图功能参数说明
可视化是数据探索性分析及结果表达的一种非常重要的形式,因此打算写一个python绘图系列,本文是第一篇,先说一下pandas.DataFrame.plot()绘图功能. pandas.DataFram ...