没有合适的资源?快使用搜索试试~ 我知道了~
14、深入理解并发可见性、有序性、原子性与JMM内存模型(1).pdf
需积分: 2 2 下载量 9 浏览量
2024-02-28
14:59:58
上传
评论
收藏 604KB PDF 举报
温馨提示
试读
13页
11-线程池 ThreadPoolExecutor 底层原理源码分析(上)-周瑜.pdf 12-线程池 ThreadPoolExecutor底层原理源码分析(下)-周瑜.pdf 13、线程池 ForkJoinPool实战及其工作原理分析 (1).pdf 14、深入理解井发可见性、有序性、原子性与JMM内存模型 (1).pdf 15、CPU缓存架构详解&高性能内存队列Disruptor 实战 (1).pdf 16、常用并发设计模式精讲 (1).pdf designpattern.zip disruptor.zip forkjoin.zip jmm(1).zip
资源推荐
资源详情
资源评论
主讲老师: Fox
有道笔记地址:
并发编程Bug的源头:原子性、可见性和有序性问题
一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。在 Java
中,对基本数据类型的变量的读取和赋值操作是原子性操作(64位处理器)。不采取任何的原子性保
障措施的自增操作并不是原子性的,比如i++操作。
下面例子模拟多线程累加操作
https://note.youdao.com/s/KiwUihrE
1. 并发三大特性
1.1 原子性
原子性案例分析
public class AtomicTest {1
private static int counter = 0;2
3
public static void main(String[] args) {4
5
for (int i = 0; i < 10; i++) {6
Thread thread = new Thread(() -> {7
for (int j = 0; j < 10000; j++) {8
counter++;9
}10
11
});12
thread.start();13
}14
15
try {16
Thread.sleep(3000);17
} catch (InterruptedException e) {18
e.printStackTrace();19
}20
21
执行结果不确定, 与预期结果不符合,存在线程安全问题
思考:在 32 位的机器上对 long 型变量进行加减操作是否存在并发隐患?
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到
修改的值。
下面是模拟两个线程对共享变量操作的例子,用来分析线程间的可见性问题
System.out.println(counter);22
23
}24
25
}26
27
如何保证原子性
通过 synchronized 关键字保证原子性
通过 Lock锁保证原子性
通过 CAS保证原子性
https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.7
1.2 可见性
可见性案例分析
public class VisibilityTest {1
2
private boolean flag = true;3
4
public void refresh() {5
// 希望结束数据加载工作6
运行结果:threadA没有跳出循环,也就是说threadB对共享变量flag的更新操作对threadA不可见,
存在可见性问题。
思考:上面例子中为什么多线程对共享变量的操作存在可见性问题?
flag = false;7
System.out.println(Thread.currentThread().getName() + "修改flag:"+flag);8
}9
10
public void load() {11
System.out.println(Thread.currentThread().getName() + "开始执行.....");12
while (flag) {13
//TODO 业务逻辑:加载数据14
15
}16
System.out.println(Thread.currentThread().getName() + "数据加载完成,跳出循环");17
}18
19
20
public static void main(String[] args) throws InterruptedException {21
VisibilityTest test = new VisibilityTest();22
23
24
// 线程threadA模拟数据加载场景25
Thread threadA = new Thread(() -> test.load(), "threadA");26
threadA.start();27
28
// 让threadA先执行一会儿后再启动线程B29
Thread.sleep(1000);30
31
// 线程threadB通过修改flag控制threadA的执行时间,数据加载可以结束了32
Thread threadB = new Thread(() -> test.refresh(), "threadB");33
threadB.start();34
35
}36
37
}38
如何保证可见性
剩余12页未读,继续阅读
资源评论
代码匠心印记
- 粉丝: 483
- 资源: 30
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- IMG_5905.PNG
- Cyclone Version 9.51
- 高性能量化回测工具 hikyuu 2.0.3 python 3.12 windows 安装包
- 省级城乡居民基本养老保险情况数据集(2010-2022年).xlsx
- 舞队填写版.cpp
- 基于BP神经网络的多输入单输出回归预测.zip
- 高性能量化回测工具 hikyuu 2.0.3 python 3.9 windows 安装包
- 省级城镇职工基本养老保险情况2000-2022年.xlsx
- 高性能量化回测工具 hikyuu 2.0.3 python 3.10 windows 安装包
- 算法部署-使用OpenVINO+C#部署PaddleOCR字符识别算法-项目源码-优质项目实战.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功