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. 6.1 集合和映射--集合Set->底层基于二叉搜索树实现

    前言:在第5章的系列学习中,已经实现了关于二叉搜索树的相关操作,详情查看第5章即可.在本节中着重学习使用底层是我们已经封装好的二叉搜索树相关操作来实现一个基本的集合(set)这种数据结构.集合set的 ...

  2. dubbo rest服务 No provider available for the service 错误问题

    1.版本 dubbo 2.6.2 2.描述 消费者调用dubbo rest服务报No provider available for the service错误 网络上有讲是实体类未实现Serializ ...

  3. 学习Flask框架

      # -*- encoding: utf-8 -*- #导包 from flask import Flask #建立flask对象 app = Flask(__name__) #使用flask路由器 ...

  4. frist Django app — 五、Test

    Test——很重要但是没有被重视起来的一个环节,至少是我自己,其实自己之前在做java web的时候就去尝试过怎么做REST接口的测试,一直没有找到一种合适方式,而且因为时间紧没有进一步深究,但是造成 ...

  5. [python]global与nonlocal关键字

    在Python中,当引用一个变量的时候,对这个变量的搜索是按找本地作用域(Local).嵌套作用域(Enclosing function locals).全局作用域(Global).内置作用域(bui ...

  6. jvm(一)类加载器

    1.jvm的生命周期结束的几种情况 a.执行了System.exit()方法 b.程序正常执行结束 c.程序在执行过程中遇到了异常或错误而异常终止 d.操作系统出现错误 2.类加载过程 加载:查找并加 ...

  7. 基于SpringBoot+Mybatis+AntDesign快速开发平台,Jeecg-Boot 1.1 版本发布

    Jeecg-Boot 1.1 版本发布,初成长稳定版本 导读     平台首页UI升级,精美的首页支持多模式 提供4套代码生成器模板(支持单表.一对多) 集成Excel简易工具类,支持单表.一对多导入 ...

  8. springboot 开启事务以及手动提交事务

    添加依赖,sprongboot 会默认开启事务管理 org.springframework.boot spring-boot-starter-jdbc 在需要的服务类里添加注解 @Autowired ...

  9. Delphi中Chrome Chromium、Cef3学习笔记(五)

    原文   http://blog.csdn.net/xtfnpgy/article/details/48489489   一.模拟移动鼠标 //  SetCursorPos(StrToInt(Edit ...

  10. (译)MySQL的10个基本性能技巧

    原文出处:https://www.infoworld.com/article/3210905/sql/10-essential-performance-tips-for-mysql.html MySQ ...