Java并发编程的艺术 记录(三)
Java内存模型
并发编程的两个关键问题:
1.线程之间如何通讯。
2.线程间如何同步。
两种方式:共享内存和消息传递。
Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。
实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享。Java线程之间的通信由Java内存模型:JMM控制。
JMM通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供内存可见性保证 。
重排序分3种类型:
1)编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
2)指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-LevelParallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
3)内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行 。
对于处理器重排序,JMM的处理器重排序规则会要求Java编译器在生成指令序列时,插入特定类型的内存屏障(Memory Barriers,Intel称之为Memory Fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序 。
happens-before规则如下:
1.·程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
2.·监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
3.·volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
4.·传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
顺序一致性,可见性保证。所有的操作按程序的顺序执行,而JMM中临界区内的代码可以重排序。
volatile写的内存语义如下。
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存。
volatile读的内存语义如下。
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。
ReentrantLock:有公平锁和非公平锁
Java线程之间的通信4种方式
1)A线程写volatile变量,随后B线程读这个volatile变量。
2)A线程写volatile变量,随后B线程用CAS更新这个volatile变量。
3)A线程用CAS更新一个volatile变量,随后B线程用CAS更新这个volatile变量。
4)A线程用CAS更新一个volatile变量,随后B线程读这个volatile变量
Java并发编程的艺术 记录(三)的更多相关文章
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- Java并发编程的艺术 记录(一)
模拟死锁 package com.gjjun.concurrent; /** * 模拟死锁,来源于<Java并发编程的艺术> * @Author gjjun * @Create 2018/ ...
- java并发编程的艺术(三)---lock源码
本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...
- Java并发编程的艺术 记录(二)
volatile的应用 volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量.Java语言提供了volatil ...
- Java并发编程的艺术(三)——synchronized
什么是synchronized synchronized可以保证某个代码块或者方法被一个线程占有,保证了一个线程的可先性.java 1.6之前是重量级锁,在1.6进行了各种优化,就不那么重了,并引入了 ...
- Java并发编程的艺术 记录(四)
Java线程的状态: new :初始状态,但是还没调用start方法. runnable:运行状态. blocked:阻塞状态. waiting:等待状态,表示当前线程需要等待其他线程作出一些特定动作 ...
- Java并发编程的艺术(三)——volatile
1. 并发编程的两个关键问题 并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行:但往往多条线程之间需要共享数据,此时在并发编程过程中就不可避免要考虑两个问题:通信 ...
- 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理
二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...
- 读《Java并发编程的艺术》(一)
离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督 ...
随机推荐
- 线程池(4)Executors.newScheduledThreadPool-只执行1次
例子1:延迟3秒后,只执行1次 ScheduledExecutorService es = Executors.newScheduledThreadPool(5); log.info("开始 ...
- 关系型数据库---MySQL---数据库设计三大范式
1.第一范式: 1.1.1 数据表的每个数据列具有原子性: 1.1.2 同一个数据表中内容相似的数据列必须消除: 2.第二范式: 第一范式的基础上,每个数据表只描述一件事: 3.第三范式: 第二范式的 ...
- missfresh问题记录
一.基本信息 1.登陆机器 ssh lina02@mjump.missfresh.net -p2222 二.问题 1.分页问题:job_id为空时能查询出来(笛卡尔乘积),需要加上AND res ...
- C8051开发环境
1 keilC51 2 Silicon Laboratories C8051Fxxx uVision Driver_4 C:\Keil9 3 Silicon Laboratories Configu ...
- AJPFX关于JAVA StringBuffer的用法总结
StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存 ...
- mongodb Limit操作
Limit() 方法 要限制 MongoDB 中的记录,需要使用 limit() 方法. limit() 方法接受一个数字型的参数,这是要显示的文档数. 语法: limit() 方法的基本语法如下 & ...
- 微信开发 config:invalid url domain
当遇到config:invalid url domain 有2种可能 1.没有配置url. 2.url配置错误.配置url如http://write.blog.csdn.NET/,就要这样配置writ ...
- Ubuntu批量修改权限
Ubuntu中有两个修改命令可以用到,「change mode」&「change owner」 即chmod以及chown,其中可以用递归参数-R来实现更改所有子文件和子目录的权限. 1.利用 ...
- Jquery 日期差函数 修改 对火狐进行兼容
function DateDiff(sDate1, sDate2) { //sDate1和sDate2是yyyy-MM-dd格式 var aDate, oDate1, oDate2, iDays; a ...
- C-C++字符输出时遇到字符'\n','\0'区别
#include "iostream" #include "stdio.h" #include "stdio_ext.h" #include ...