前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JMM学习笔记

JMM学习笔记

作者头像
itliusir
发布2018-10-08 11:00:12
3770
发布2018-10-08 11:00:12
举报
文章被收录于专栏:刘君君刘君君

摘要:JMM学习笔记

正文:

Java Memory Model

未同步的程序的行为

语句重排序
语句重排序

如上面例子所示

有 A B 两个共享变量,r1 r2 两个局部变量

要出现 May observer r2 == 2,r1 == 1 线程执行顺序应该是如下所示:

Thread 1:B=1 Thread 2:r1=B Thread 2:A=2 Thread 1:r2=A

而按照程序员视角看第一个原始指令与实际的结果,可能会感觉很困惑,其根本原因是Java 的语义允许编译器和微处理器进行优化,这则会影响未正确同步的代码的行为 (如上代码是未同步的)。

非正式语义

看一个程序是否被正确的同步有两个关键概念

冲突访问

对共享元素存在数据竞争场景,如上文中的未同步程序的行为

Happens-Before 关系

happens-before 关系可以对两个动作进行排序,如果一个动作 happens-before 另一个动作,则第一个对第二个可见,且第一个排在第二个之前。必须强调的是,两个动作之间存在 happens-before 关系并不意味着这些动作在Java中必须以这种顺序发生。happens-before 关系主要用于强调两个有冲突的动作之间的顺序,以及定义数据争用的发生时机

如果某个动作A happens-before 动作B,且B happens-before 动作C,则有A happens-before C

顺序一致性

顺序一致性是程序执行过程中可见性和顺序的强有力保证,在顺序一致性内存模型中,每个操作都必须是原子执行且对所有线程可见

final 字段

声明为 final 的字段在 对象完全初始化后的时刻 值是不可变的,所以 final 字段也允许编程人员在不需要同步的情况下实现线程安全的不可变对象

什么是内存模型

内存模型可以看做为一组规则,规定了一个线程的写操作何时会对另一个线程可见

定义

Shared variables/Heap memory

能够在线程间共享的内存称为共享内存或堆内存,所有的实例字段,静态字段以及数组元素都存储在堆内存中,方法中的局部变量永远不会在线程间共享且不会被内存模型影响

Inter-thread Actions

线程间的动作是某一个线程执行的动作能被另一个线程探测或影响,比如lock某个管城、读写volatile变量

我们无需关心 Intra-thread 动作(线程内部) ,每个单线程需要遵守正确的 Intra-thread semantics

Intra-thread semantics

线程内语义是单线程程序的标准语义,线程内语义决定着某个线程孤立的执行过程,当从堆中读取值时,值是由内存模型决定的

Synchronization Actions

同步动作包括锁、解锁、读写 volatile 变量等动作

近似模型

在上文的非正式语义中描述了顺序一致性,在顺序一致性内存模型中,每个操作都必须是原子执行且对所有线程可见。其约束较严格,禁止了编译器和处理器优化,不适合做 Java 内存模型

Java中,共享变量(实例、静态、数组元素)存在堆内存中,堆内存在线程之间共享。非共享变量(局部变量、方法定义参数、异常处理参数)不会在线程之间共享,它们不会有内存可见性的问题

在JMM(Java Memory Model,java 内存模型)中,其

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文:
  • Java Memory Model
    • 未同步的程序的行为
      • 非正式语义
        • 顺序一致性
        • final 字段
      • 什么是内存模型
        • 定义
        • 近似模型
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档