美文网首页
Java多线程之有序性(二)

Java多线程之有序性(二)

作者: NEU_PROYZ | 来源:发表于2018-05-07 21:08 被阅读15次

好了,上一章我们讲了有序性出现问题的原因,今天我们来细讲一下有序性的保证方式。
书上有一段比较匪夷所思的关于有序性定义。
有序性:指在什么情况下一个处理器上运行的一个线程所执行的内存访问在另一处理器运行的另外一个线程看来是乱序的
乱序是指内存访问的顺序看起来像是发生了变化。
我不随意揣测这个定义了,看不懂也没关系,我们接着看下面就好了。

我对有序性的理解是,对于共享变量的操作一定要按我们的代码逻辑顺序执行,避免多线程情况下由于重排导致的错误。细点说就是,临界区内与临界区外的代码你可以重排序,我管不着,因为你不影响共享变量的值。但是,你不能将临界区内的代码重排到临界区外面,当然临界区外的代码进入临界区其实是没影响的。
那么java底层是靠什么实现的呢?靠的是一种叫做内存屏障的东西。
内存屏障:针对跨处理器的读写操作,它被插入到两个指令之间,作用是禁止编译器和处理器重排序。为了禁止重排序,就像是在指令之间建起了一堵墙。
同时,内存屏障也有一个作用就是保证了可见性,因为它可以产生刷新处理与冲刷处理器的效果。先看一张图,

Barrier.png
我们按可见性分类,把屏障可以分为两类:加载屏障(Load Barrier)存储屏障(Store Barrier)
加载屏障:刷新处理器缓存。
存储屏障:冲刷处理器缓存。
JVM会在MonitorEnter(申请锁)对应的机器码指令后面临界区代码开始之前插入Load Barrier,以达到临界区内部使用的共享变量都是新值。同样,会在MonitorExit(释放锁)对应的指令后插入Store Barrier,以达到临界区对共享变量的更改及时写回主存。

再按有序性划分:分为获取屏障(Acquire Barrier)释放屏障(Release Barrier)
获取屏障:在一个读操作之后插入一个屏障,禁止与之后的任何读写操作重排。
释放屏障:在一个写操作之前插入一个屏障,禁止与其前面任何读写操作重排。
JVM会在MonitorEnter(申请锁)对应的机器码指令后面临界区代码开始之前插入Acquire Barrier,并在临界区之后MonitorExit之前插入Release Barrier。

到这,三个重要的性质就讲完了,之后再陆陆续续写点别的,也只是把我的笔记誊抄一遍,还有很多东西我理解的也不深,很表面,甚至会有错误,希望大佬不吝赐教。

相关文章

  • java内存模型

    多线程的三大特性: 原子性,独一无二,一致性,保证线程安全问题 可见性:java内存模型 有序性:join,wai...

  • 带你搞懂Java多线程(五)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四) ...

  • 带你搞懂Java多线程(六)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三)带你搞懂Java多线程(四)带...

  • Java多线程有序性

    有序性(Ordering)是指在什么情况下一个处理器上运行的一个线程所执行的 内存访问操作在另外一个处理器运行的其...

  • Java-可见性、原子性、有序性

    关键字:Java内存模型(JMM)、线程安全、可见性、原子性、有序性 1.线程安全(JMM) 多线程执行某个操作的...

  • Java多线程之有序性(二)

    好了,上一章我们讲了有序性出现问题的原因,今天我们来细讲一下有序性的保证方式。书上有一段比较匪夷所思的关于有序性定...

  • 理解java中的Synchronized关键字

    开篇知识了解 插入知识 JMM(java内存模型)的关键技术都是围绕着多线程的原子性,可见性,有序性来建立的。因此...

  • 带你搞懂Java多线程(四)

    带你搞懂Java多线程(一)带你搞懂Java多线程(二)带你搞懂Java多线程(三) 什么是线程间的协作 线程之间...

  • java多线程编程-有序性

    有序性 有序性 (Ordering) 指的是在什么情况下一个处理器上运行的一个线程所执行的内存访问操作在另一个处理...

  • Reentranlock

    Java多线程(九)之ReentrantLock与Condition

网友评论

      本文标题:Java多线程之有序性(二)

      本文链接:https://www.haomeiwen.com/subject/vmzvrftx.html