Fork me on GitHub

java 内存模型如何解决可见性和有序性问题

java 内存模型如何解决可见性和有序性问题

看标题联想

  1. happen before 原则
  2. 之后就是并发编程实战中的图形 cmp等命令
  3. 内存模型 又想到什么?
  4. 导致可见性就是因为cup的缓存,有序性就用volatile关键字呗
    按需禁用缓存以及编译优化
    java 内存模型很复杂,synchronized ,volatile ,final 还有happen-before 6个原则
    volatile 在1.5版本才解决的可见性问题,因为加入了happen-before原则。
    前一个操作的结果对后续操作是可见的,这个是happen-before的原则。
  • 程序顺序规则

    指的是在一个线程中前边的代码happen-before后边任意的操作

  • volatile 变量规则

    这条规则是指对一个 volatile 变量的写操作, Happens-Before 于后续对这个 volatile变量的读操作,需要结合第三条传递性看

  • 传递性

    A于B 操作前,B于C 操作前,那么A 必然于C 前

    简单分析:
    A x=42 在v=true 之前 这是A的规则,B v=true 于 读变量x 前,那么最后的结果是x =42 ,这就是传递性 最终B能读取到A的变量 x =42

  • 管程中锁的规则

    管程在java 里就是synchronized 的实现 ,指的是一个管程的解锁于后续对这个锁的加锁前。
    // todo没太理解,例子就是synchronized 加锁 解锁是jvm 底层用ACC-synchronized 的命令实现,而且是自动加锁和释放锁

  • 线程 start() 规则
    比如A中启动一个线程B ,B能看到A 启动B 之前的操作 ,在A调用b.start()前 所有的操作Happens-Before 于线程 B 中的任意操作
    

  • 线程 join() 规则

    主线程调用B线程中的join 方法,那么等B线程执行完毕,那么B线程中的操作happen-before于A 调用B的join操作的返回,也就是主线程能看到join之后b线程的操作。

  • 被忽略的final 关键字

    用final 修饰的关键字,认为是不可变的,但是要防止逸出
    小结:
    其实happen-before的规则在java 语义中就是可见性,如果A happen-before B ,那么A事件对B事件就是可见的,不论发生在一个或者多个线程里。
    线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事 件的发生,可以通过Thread.interrupted()方法检测到是否有中断发生。
    对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法 的开始

本文欢迎转载,但是希望注明出处并给出原文链接。 如果你有任何疑问,欢迎在下方评论区留言,我会尽快答复。 如果你喜欢或者不喜欢这篇文章,欢迎你发邮件到 alonecong@126.com 告诉我你的想法,你的建议对我非常重要。

------ 本文结束感谢您的阅读! ------
0%