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同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
随机推荐
- php数据映射到echarts中国地图
echarts和php结合 根据php后台数据,映射到地图上所有的省份,地图市下钻的形式,每次下钻到新地图不合并(合并缩放的话会导致下钻地图位置找不到了),添加了自定义工具栏里面的返回到顶级下钻地图 ...
- Thinkphp3.2 cms之分类管理
四.分类管理 <?php namespace Admin\Controller; use Think\Controller; class CateController extends Contr ...
- 在java9+版本中,接口的内容和注意
1.成员变量其实就是常量,格式: [public] [static] [final] 数据类型 常量名称 = 数据值: 注意: 常量必须进行赋值,而且一旦赋值不能改变. 常量名称完全大写,用下划线进行 ...
- mysql 定时任务执行
SET GLOBAL event_scheduler = ON; show variables like 'event_scheduler'; event_scheduler ON 创建event: ...
- Life is Strange 完结感想
Life is Strange 是一款剧情游戏.steam上第一章是免费的,也正是因为这个我才开始了解到这个游戏,玩完第一章后觉得还可以,就趁打折花了17块钱买了2-5章.应该是18年6月20号买的, ...
- Scrum转型(一) 为什么敏捷和Scrum
1.1 为什么敏捷 由于传统的瀑布模型管理方法无法满足现代某些软件产品开发过程的特点,我们需要使用敏捷的方法(例如,Scrum是一个让我们关注于在短时间里交付高质量商业价值的敏捷框架). 需求频繁变动 ...
- ceph单机多mon的实现
ceph默认情况下是以主机名来作为mon的识别的,所以这个情况下用部署工具是无法创建多个mon的,这个地方使用手动的方式可以很方便的创建多个mon 1.创建mon的数据存储目录 mkdir /var/ ...
- Python_网络编程_socket()
什么是 Socket? Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 详细资 ...
- kettle练习
Kettle实现,把数据从CSV文件复制到Excel文件. 首先,创建一个转换,找到核心对象,找到输入里面的CVS文件输入图元,拖拽到工作区域,双击CVS文件输入. 可以修改步骤的名称,点击浏览,选择 ...
- GreenDao增删改查
3.GreenDao增删改查 (1)插入 常用API //这是最简单的插入语句,新增一行数据,返回值为行号 public long insert(T entity) //传递一个数组,新增多行数据 p ...