Java内存模型

一、Java内存模型的基础

1.并发编程模型的两个关键问题:

两个关键问题,线程之间如何通信和如何同步。两种方式,共享内存和消息传递。Java里线程的通信是通过共享内存,线程的同步是显示进行的,而通信则是隐式进行的。

2.Java内存模型的抽象结构:

实际上就是说Java线程之间的通信是通过共享内存来进行交互。

3.从源代码到指令序列的重排序:

重排序,让指令序列重新排序而更高效地运行程序。Java中根据不同的处理器会禁用对应的重排序规则(内存屏障),从而保证了内存可见性。

4.并发编程模型的分类:

对于处理器来说主要需要重排序的操作是:写-读操作,否则可能会导致数据的脏读。不同的处理器分别在“读-读”、“写-写”、“读-写”、“写-读”操作上可能都有可能进行重排序。而在不需要重排序的处理器上,Java提供了内存屏障指令来避免没有必要的重排序。

5.happens-before概念:

操作A happens-before 操作B,那么操作A的结果就对操作B可见,happens-before概念并不意味着操作A就一定发生在操作B之前。

二、重排序

对指令的重排序是对程序执行的一种优化;

1.数据依赖性

如果两个操作操作同一数据,只要有个操作是“写”,那么这两个操作之间存在数据依赖性;

2.as-if-serial语义

不管怎么重排序,单线程的处理结果不能被改变;

3.重排序对多线程的影响

两个线程分别操作两个数据,线程A的两个数据没有数据依赖性,而线程B的两个数据存在数据依赖性,那么线程A中可能发生的重排序可能会影响到线程B的操作的结果。

三、顺序一致性

顺序一致性模型是一个理想化的内存模型;

1.数据竞争与顺序一致性

数据竞争:两个线程之间,线程A在写一个数据,线程B又在读这个数据,并且两个线程没有做同步;而在JMM中,做了同步操作的结果可以保证和顺序一致性模型的结果保持一致;

2.顺序一致性内存模型

顺序一致性的两大特性:

(1)一个线程的所有操作必须按照程序的顺序执行;

(2)不管是否同步,所有线程只能看到单一的操作执行顺序;

3.同步程序的顺序一致性效果

同步的程序之间,临界区内的代码可能会进行重排序,但是最终的结果和顺序一致性模型是一样的,这样就既保证了顺序一致性的效果,又能对性能进行优化;

4.未同步程序的执行特性

四、volatile的内存语义

1.volatile特性:

有 volatile  变量的方法相当于加了  synchronized 锁;

2.volatile内存语义:

两个分别对同一个 volatile 变量进行写和读的线程:

(1)写线程在写了之后,读线程才去读这个写线程发出(修改)的信息;写线程在把本地内存的信息写了之后,刷新到共享内存中;

(2)读线程读一个变量,相当于读了写线程写了之后的变量;

(3)相当于写线程和读线程之间的通信;

五、锁的内存语义

1. 锁获取与锁释放内存语义:

synchronized 锁与 volatile 的内存语义:锁获取与volatile读有相同内存语义,锁释放与volatile写有相同内存语义;

2.锁的源码分析:

以 ReentrantLock 为例:

公平锁:

(1)lock()方法获取锁,最终调用tryAcquire()方法,读取volatile变量;

(2)unlock()方法释放上锁,最终调用tryRelease()方法,写volatile变量;

非公平锁:

(1) lock() 方法最终会去调用CAS方法去更新volatile变量,从而有volatile读写共有的内存语义;

六、final域的内存语义:

1.final域修饰基本数据类型成员变量:

JMM不会将构造函数中的写final域与其它线程中的读final域进行重排序,不会将写final域操作重排序在构造函数外面;

2.final域修饰引用类型成员变量:

构造函数中,final域修饰的引用成员变量的任何操作都不会重排序在构造函数外部,比如在构造函数中读引用变量,使用引用变量给赋值,而在其它线程方法中给此引用变量赋值则可能被重排序到读操作之后;

七、happens-before规则

《Java并发编程的艺术》Java内存模型(三)的更多相关文章

  1. JAVA并发编程的艺术 JMM内存模型

    锁的升级和对比 java1.6为了减少获得锁和释放锁带来的性能消耗,引入了"偏向锁"和"轻量级锁". 偏向锁 偏向锁为了解决大部分情况下只有一个线程持有锁的情况 ...

  2. JAVA并发编程的艺术 Java并发容器和框架

    ConcurrentHashMap ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成. 一个ConcurrentHashMap里包含一个Segment数组, ...

  3. java并发编程(9)内存模型

    JAVA内存模型 在多线程这一系列中,不去探究内存模型的底层 一.什么是内存模型,为什么需要它 在现代多核处理器中,每个处理器都有自己的缓存,定期的与主内存进行协调: 想要确保每个处理器在任意时刻知道 ...

  4. Java并发编程的艺术读书笔记(2)-并发编程模型

    title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...

  5. 读《Java并发编程的艺术》(一)

    离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督 ...

  6. Java并发编程的艺术(三)——volatile

    1. 并发编程的两个关键问题 并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行:但往往多条线程之间需要共享数据,此时在并发编程过程中就不可避免要考虑两个问题:通信 ...

  7. 《Java并发编程的艺术》留给自己以后看的笔记

    <Java并发编程的艺术>这本书特别好,和<深入了解JAVA虚拟机>有一拼,建议做java的都看看,下面全部都是复制书中的部分内容,主要目的是做个笔记,方便以后遇到问题能找到. ...

  8. 读书笔记之《Java 并发编程的艺术》

    一.多线程语义 即使是单核处理器也支持多线程执行代码,CPU 通过给每个线程分配 CPU 时间片来执行任务,当前任务执行一个时间片后会切换到下一个任务,所以 CPU 通过不停的切换线程执行. 并发执行 ...

  9. 【Java并发编程】从CPU缓存模型到JMM来理解volatile关键字

    目录 并发编程三大特性 原子性 可见性 有序性 CPU缓存模型是什么 高速缓存为何出现? 缓存一致性问题 如何解决缓存不一致 JMM内存模型是什么 JMM的规定 Java对三大特性的保证 原子性 可见 ...

  10. 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理

    二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...

随机推荐

  1. HTTPS 基本流程3

    前文说到了6 组key material, 12个hash 值,非常迷惑, 今天才搞明白, 原来所有这些内容就是 对称密钥的内容. 上面的图 虽然不是很清晰,但是, 其实也已经写明白了, 就是 右边的 ...

  2. Spring MVC参数封装传递

    在Spring MVC中,前端JSP页面可以传递  基本类型(int,String).实体类型.包装类型.数组类型.集合类型(List.map )等. 假如在传递的类型中有 Date类型的字段,需要在 ...

  3. sql 条件汇总

    select * from a pivot(sum([总业绩]) for 周期 in ([1月],[2月],[3月],[4月])) as b

  4. MTK之DrvGen的使用

    打开mcu\custom\drv\Drv_Tool [L206X_code20190321\custom\drv\Drv_Tool]下的DrvGen.exe,如下图所示: 点击"Open&q ...

  5. java高并发实战(三)——Java内存模型和线程安全

    转自:https://blog.csdn.net/gududedabai/article/details/80816488

  6. elk报警监控之sentinl 钉钉+邮件告警

    注:我的elk sentinl版本都是6.5.1 前期知识 es的查询语法.es watcher使用方法. https://www.cnblogs.com/pilihaotian/p/5830754. ...

  7. ThinkPHP实现支付宝接口功能 代码实例

    我们这里用的是即时到帐的接口,具体实现的步骤如下: [title]一.下载支付宝接口包[/title]下载地址:https://doc.open.alipay.com/doc2/detail?tree ...

  8. java使用c3p0连接mysql,写中文数据乱码的问题

    此文说的乱码,是指所有中文的字符都变成了?. 首先,网上普遍搜索到的解决方案都是告诉你要在数据库连接字符串里面增加编码的定义,完整的连接字符串如下: url="jdbc:mysql://12 ...

  9. Day01 -Class类别 精选面试题

    30天修炼完成Ruby精选面试题! 我决定从学习Ruby on Rails开始着手!鼓励自己在短期间内专心学习与产出知识,为转职奠定良好的基础. A.首先:找寻方向,决定主题 我想很多人的状况都跟我一 ...

  10. TS和C#的差异

    1. TS中let a : () => void; 假设有个class  B,  B里有个方法 c; 不能像C#委托一样, a = B.c;...........如果这样的话方法c里调用的thi ...