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. es6 和 python 语法比较

    http://www.linchaoqun.com/html/cms/content.jsp?id=1509528630774 Python3笔记:Python与ECMAScript部分语法对比 ht ...

  2. Android中四大组件总结

    android四大组件分别为activity.service.content provider.broadcast receiver. 一.android四大组件详解 1.activity (1)一个 ...

  3. jpa @RepositoryRestResource

    依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spr ...

  4. javascript判断字符串相等

  5. FICO-初级会计学

    初级会计学 https://wenku.baidu.com/view/39257b1a59eef8c75fbfb348.html?from=search https://wenku.baidu.com ...

  6. Spring.xml中配置注解context:annotation-config和context:component-scan简述

    XML中context:annotation-config和context:component-scan简述 <context:annotation-config/> 中文意思:<上 ...

  7. getPageNumRange

    <script> function getPageNumRange(pagenumstr) { var pages=pagenumstr.split(";"); pag ...

  8. Day07 - Ruby比一比:Symbol符号与String字串

    前情提要: 第六天我们透过Ruby代码练习public,protected和privatemethod时,发现冒号在前面的参数,:mydraft,:myspace,这些就是符号Symbol.在今天,我 ...

  9. 需要转义的java字符(转)

    特别字符 说明 $ 匹配输入字符串的结尾位置.如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n' 或‘\r'.要匹配 $ 字符本身,请使用 \$. ( ) 标记一个子 ...

  10. 知识点---<input>、<textarea>

    一.在pc端的input是一个大的知识点 [1]文本框 <input type="text"> [2] 密码框 <input type="passwor ...