请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

并发编程之Java内存模型

[复制链接]
查看: 92|回复: 0

3万

主题

3万

帖子

9万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
92753
发表于 2020-2-15 11:30 | 显示全部楼层 |阅读模式
并发编程之Java内存模子


5.1 Java内存模子

JMM即Java Memory Model,它界说了主存、工作内存笼统概念,底层对应着CPU寄存器、缓存、硬件内存、CPU指令优化等。
JMM表现在以下几个方面

  • 原子性 - 保证指令不会遭到线程高低文切换的影响
  • 可见性 - 保证指令不会受cput缓存的影响
  • 有序性 - 保证指令不会受cpu指令并行优化的影响
5.2 可见性

退不出的循环
先来看一个现象,main线程对run变量的点窜对于t线程不偏见,致使了t线程没法禁止 :
我的关键词 并发编程之Java内存模子  热门消息 20200213082625584

为什么呢?分析一下 :
1.初始状态,t线程刚起头从主内存读取了run的值到工作内存。
我的关键词 并发编程之Java内存模子  热门消息 20200213082900838

2. 由于t线程要频仍从主内存中读取run的值,JIT编译器会将run的值缓存至自己工作内存中的高速缓存中,淘汰对主存中run的拜候,进步服从
我的关键词 并发编程之Java内存模子  热门消息 20200213083114866

3. 1秒以后,main线程点窜了run的值,并同步至主存,而t是从自己工作内存中的高速缓存中读取这个变量的值,成果永久是旧值
我的关键词 并发编程之Java内存模子  热门消息 20200213083317256

治理方式
volatile(易变关键字)
它可以用来修饰成员变量和静态成员变量,它可以制止线程从自己的工作缓存中查找变量的值,必须到主存中获得它的值,线程操纵volatile变量都是间接操纵主存。
可见性 VS 原子性
前面例子表现的现实就是可见性,它保证的是在多个线程之间,一个线程对volatile变量的点窜对另一个线程可见,不能保证原子性,仅用在一个写线程,多个读线程的情况 :
上例从字节码大白是这样的 :
我的关键词 并发编程之Java内存模子  热门消息 20200213084449643

比力一下之前我们将线程平安时举的例子 :两个线程一个i++ 一个i–,只能保证看到最新值,不能治理指令交织
我的关键词 并发编程之Java内存模子  热门消息 20200213084803623

留意
synchronized语句块既可以保证代码块的原子性,也同时保证代码块内变量的可见性。但弱点是synchronized是属于重量级操纵,性能相对更低。
假如在前面示例中的死循环中加入System.out.println()会发现即使不加volatile修饰符,线程t也能切确看到对run变量的点窜了,想一想为什么?
5.3 有序性

JVM会在不影响切确性的条件下,可以调解语句的实行次第 :
我的关键词 并发编程之Java内存模子  热门消息 20200214161058429

可以看到,至因而先实行i还是先实行j,对终极的成果不会发生影响。所以,上面代码真正实行时,既可所以
我的关键词 并发编程之Java内存模子  热门消息 20200214161150259

也可以是
我的关键词 并发编程之Java内存模子  热门消息 20200214161204328

这类特征称之为指令重排,多线程下指令重排会影响切确性。
volatile道理

volatile的底层实现道理是内存屏障,Memory Barrier(Memory Fence)

  • 对volatile变量的写指令后后加入写屏障
  • 对volatile变量的读指令前会加入读屏障

  • 怎样保证可见性


  • 写屏障(sfence)保证在该屏障之前的,对同享变量的修改,都同步到主存傍边
    我的关键词 并发编程之Java内存模子  热门消息 20200214165156413

  • 而读屏障(lfence)保证在该屏障以后,对同享变量的读取,加载的是主存中最新的数据
    我的关键词 并发编程之Java内存模子  热门消息 20200214165427425

    我的关键词 并发编程之Java内存模子  热门消息 20200214165715461

    2.怎样保证有序性
  • 写屏障会确保指令重排序时,不会将写屏障之前的代码排在写屏障以后
    我的关键词 并发编程之Java内存模子  热门消息 20200214165858452

  • 读屏障会确保指令重排序时,不会将读屏障以后的代码排在读屏障之前
    我的关键词 并发编程之Java内存模子  热门消息 20200214170024942

    我的关键词 并发编程之Java内存模子  热门消息 202002141700559

    不能治理指令交织 :
  • 写屏障仅仅是保证以后的读可以大要读到最新的成果,但不能保证读跑到它前面去
  • 而有序性的保证壹泵η保证了本线程内相关代码不被重排序
    我的关键词 并发编程之Java内存模子  热门消息 20200214170354934

double-checked locking 单例形式为例

我的关键词 并发编程之Java内存模子  热门消息 20200214171655420

以上的实现特点是 :

  • 怠惰实例化
  • 初度操纵getInstance()才操纵synchronized加锁,后续操纵时无需加锁
  • 有隐含的,但很关键的一点 : 第一个if操纵了INSTANCE变量,是在同步块之外
    但在多线程情况下,上面的代码是有题目标,getInstance方式对应的字节码为 :
    我的关键词 并发编程之Java内存模子  热门消息 20200214172140685

    其中
  • 17表示建立工具,将工具援用入栈 // new Singleton
  • 20表示复制一份工具援用 // 援用地址
  • 21表示操纵一个工具援用,挪用机关方式 // 按照援用地址挪用
  • 24表示操纵一个工具援用,赋值给 static INSTANCE
    大要jvm会优化为 : 先实行24,再实行21.假如两个线程t1,t2按以下时候序列实行 :
    我的关键词 并发编程之Java内存模子  热门消息 20200214172704571

    关键在于 0 :getstatic这行代码在monitor控制之外,它就像之前举例中不守法则的人,可以超出monitor读取INSTANCE变量的值
    这时t1还未完成将机关方式实行终了,假如在机关方式中要实行很多初始化操纵,那末t2拿到的是将是一个未初始化终了的单例
    对INSTANCE操纵volatile修饰即可,可以禁用指令重排,但要留意在JDK5以上版本的volatile才会真正有用
4.double-checked locking 治理

我的关键词 并发编程之Java内存模子  热门消息 20200214174726600

字节码上看不出来volatile指令的成果
我的关键词 并发编程之Java内存模子  热门消息 20200214174812905

我的关键词 并发编程之Java内存模子  热门消息 20200214174933454

happens-before
happens-before规定了对同享变量的写操纵对此外线程的读操纵可见,它是可见性与有序性的一套法则总结,抛开以下happens-before法则,JMM并不能保证一个线程对同享变量的写,对于此外线程对该同享变量的读可见

  • 线程解锁m之前对变量的写,对于接下来对m加锁的此外线程对该变量的读可见
    我的关键词 并发编程之Java内存模子  热门消息 20200214175448899

  • 线程对volatile变量的写,对接下来此外线程对该变量的读可见
    我的关键词 并发编程之Java内存模子  热门消息 20200214175818831

  • 线程start前对变量的写,对该线程起头后对该变量的读可见
    我的关键词 并发编程之Java内存模子  热门消息 20200215084347204

  • 线程竣事前对变量的写,对此外线程得知它竣事后的读可见(比如此外线程挪用t1.isAlive()或t1.join()期待它竣事)
    我的关键词 并发编程之Java内存模子  热门消息 20200215084507628

  • 线程t1打断t2(interrupt)前对变量的写,对于其他线程得知t2被打断后对变量的读可见(经过t2.interrupted或t2.interrupted)
    我的关键词 并发编程之Java内存模子  热门消息 20200215084658930

  • 对变量默许值(0,false,null)的写,对此外线程对该变量的读可见
  • 具有转达性,假如x hb -> z 那末有x hb -> z,配合volatile的防指令重排,有下面的例子
    我的关键词 并发编程之Java内存模子  热门消息 2020021508560339

    变量都是指成员变量或静态成员变量

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 WAYSFOCUS 影像 你 我 他,中国商业影视一站式解决平台 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表