java并发编程实战《二》java内存模型
Java解决可见性和有序性问题:Java内存模型
什么是 Java 内存模型?
Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为,
Java 内存模型规范了 JVM 如何提供按需禁用缓存和编译优化的方法。具体来说,这些方法包括 volatile、synchronized 和 final 三个关键字,以及六项 Happens-Before 规则。
Happens-Before 规则:前一个操作的结果对后续操作可见。
- 程序的顺序性规则程序的顺序性规则程序的顺序性规则程序的顺序性规则
程序的顺序性规则
- 在一个线程中,按照程序顺序,对前部分代码的操作对后面的操作是可见的
- volatile规则
- 对volatile变量的写相对于volatile变量的读可见
- 传递性规则
- a对b可见,b对c可见,则a对c可见
- 管程中锁的规则
- 对一个锁的解锁对后续对这个锁的加锁可见
- 线程 start() 规则
- 指主线程 A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程 B 前的操作。
-
1 package com.jeek_time.java并发编程实战.二.happensbefore;
2
3 /**
4 * 测试happens-before中的start规则
5 * 主线程中start子线程B,在start B线程时可看到主线程对共享变量的操作, 0 -> 1
6 */
7 class TestStart{
8 static int i=0;
9 public static void main(String[] args) {
10 i=1;
11 final Thread subThreadB = new Thread(() ->{
12 System.out.println(TestStart.i);
13 });
14 subThreadB.setName("子线程B");
15 subThreadB.start();
16 }
17 }
- 线程 join() 规则
- 指主线程 A 等待子线程 B 完成(主线程 A 通过调用子线程 B 的 join() 方法实现),当子线程 B 完成后(主线程 A 中 join() 方法返回),主线程能够看到子线程的操作(共享变量)
- 下面这段代码的结果:先0后1,刚好可印证结论,很有趣。
1 package com.jeek_time.java并发编程实战.二.happensbefore;
2
3 import lombok.SneakyThrows;
4
5 /**
6 * 测试happens-before中的join规则
7 * 指主线程等待子线程 B 完成(主线程通过调用子线程 B 的 join() 方法实现),
8 * 当子线程 B 完成后(主线程中 join() 方法返回),主线程能够看到子线程B的操作(共享变量)
9 */
10 public class TestJoin{
11 static int i = 0;
12 @SneakyThrows
13 public static void main(String[] args) {
14 final Thread subThreadB = new Thread(() ->{
15 TestJoin.i = 1;
16 try {
17 Thread.sleep(1000);
18 } catch (InterruptedException e) {
19 e.printStackTrace();
20 }
21 });
22 subThreadB.setName("子线程B");
23 subThreadB.start();
24
25 System.out.println("返回前:" + TestJoin.i);
26 subThreadB.join();
27 System.out.println("返回后:" + TestJoin.i);
28 }
29
30 }
2 final int x;
3 // 错误的构造函数
4 public FinalFieldExample() {
5 x = 3;
6 y = 4;
7 // 此处就是讲this逸出,
8 global.obj = this;
9 }
- 声明共享变量abc,并使用volatile关键字修饰abc
- 声明共享变量abc,在synchronized关键字对abc的赋值代码块加锁,由于Happen-before管程锁的规则,可以使得后续的线程可以看到abc的值。
- A线程启动后,使用A.JOIN()方法来完成运行,后续线程再启动,则一定可以看到abc==3
摘自极客时间王宝令老师的课程
java并发编程实战《二》java内存模型的更多相关文章
- java并发编程(9)内存模型
JAVA内存模型 在多线程这一系列中,不去探究内存模型的底层 一.什么是内存模型,为什么需要它 在现代多核处理器中,每个处理器都有自己的缓存,定期的与主内存进行协调: 想要确保每个处理器在任意时刻知道 ...
- JAVA并发编程的艺术 JMM内存模型
锁的升级和对比 java1.6为了减少获得锁和释放锁带来的性能消耗,引入了"偏向锁"和"轻量级锁". 偏向锁 偏向锁为了解决大部分情况下只有一个线程持有锁的情况 ...
- java并发编程实战(java concurrency in practice)
第一章 线程共享进程范围内的资源,但每个线程都有各自的程序计数器.栈以及局部变量等. 多个线程可以同时调度到多个CPU上运行. 线程的优势? 在服务应用程序中,可以提升资源利用率以及系统吞吐率 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- Java并发编程实战——读后感
未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介
注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...
- java并发编程实战学习(3)--基础构建模块
转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...
- 《java并发编程实战》笔记
<java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为: Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...
- 《Java并发编程实战》文摘
更新时间:2017-06-03 <Java并发编程实战>文摘,有兴趣的朋友可以买本纸质书仔细研究下. 一 线程安全性 1.1 什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何 ...
随机推荐
- malloc,calloc,realloc三者的区别
malloc,calloc,realloc三者都可以运用与动态分配数组. malloc:用malloc必须要自己初始化,可以用memset(arr,0,cnt*sizeof(int)) calloc: ...
- java实现KFC点餐系统
这篇文章主要为大家详细介绍了java实现KFC点餐系统,模拟肯德基快餐店的收银系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 同学们应该都去麦当劳或肯德基吃过快餐吧?请同学们参考肯德基官网的信 ...
- Manacher (马拉车) 算法:解决最长回文子串的利器
最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...
- 使用webapi绑定layui数据表格完整增删查改记录
因为每次给layui数据表格绑定数据或者类似操作的时候 总要重新做一遍 而且忘记很多东西 所以干脆写博客把相关东西记录下来 便于查阅和修正 以下是一个完整的数据表格i项目的增删改查案例 先来看后台 ...
- CDM 设置 主键自增
一些朋友在用PD建概念模型时,觉得主键无法设置自增,还需要在生成PDM后,单独再设置一次,很麻烦. 自增主键一般都是整形,int ,long 如果我们在CDM建实体模型时,将自增主键设置为Serial ...
- Flutter(75):Sliver组件之SliverFixedExtentList
Flutter教学目录持续更新中 Github源代码持续更新中 1.SliverFixedExtentList 可以固定Item高度的SliverList 2.SliverFixedExtentLis ...
- 数组和list 相互转换中遇到的坑
代码示例: public class ArrayDemo { public static void main(String[] args) { Integer[] arr = {1, 2, 3, 4, ...
- 有了Cloud Alert电话报警,再也不怕遗漏告警了
Cloud Alert 的部分应用部署在阿里云上,使用了多方面的监控服务: 阿里自身的ECS服务器和网站. Zabbix 监控服务器应用程序. OneAPM 的应用级监控. 腾讯云拨测,做网站监控. ...
- 重看 mb volatile atomic
在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的.为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执 ...
- git操作之三:git reset
在上篇文章中介绍了git restore命令,该命令的可以看作是撤销命令,文件在不同的状态下,使用git restore <file> 命令,会撤销对文件的修改,是文件回到修改前的状态也就 ...