前面两篇文章讲解过了深刻并发编程模型基本概念和重排序,尚未阅读过前面两篇文章的建议阅读下:程序员
顺序一致性,简单理解为:就是程序的执行顺序和它编写的顺序一致编程
顺序一致性内存模型是一个被计算机科学家理想化了的理论参考模型,它为程序员提供了极强的内存可见性保证。顺序一致性内存模型有两大特性:segmentfault
也就是说,一个线程看到的程序的执行顺序,是和它的代码的编写顺序一致的。好比在一个线程中,代码逻辑是先编写A,再编写B,最后再编写C,那么在一致性模型的约束下,程序的执行顺序是 A -> B -> C 。是不会发生指令重排序的。(不要搞混,重排序是在JMM模型下实现的,并非一致性模型下实现。它俩的区别下文会讲。)
例如,在一致性模型约束下,程序执行顺序和代码编写顺序一致。即便是A、B、C操做执行顺序互不影响程序结果,也不会改变程序执行顺序。并发
在顺序一致性内存模型中,每一个操做都必须原子执行且马上对全部线程可见。也就是说,多个线程之间,无论程序是否同步,它们看到的执行顺序是一致的。不可能A线程看到的程序执行顺序和B线程看到的执行顺序是不一致的。
例以下图,无论程序是否执行了同步,一、2线程看到的总体程序执行顺序是一致的。app
好比进行了同步,线程一、2看到的执行顺序是 A -> B -> C -> D -> E -> F ,或者 D -> E -> F -> A -> B -> C 。不会出现不一致。若是未进行了同步,那么ABC、DEF的执行顺序总体是有序的,也就是说会遵照 B 或 C 不会在 A 以前执行,可是可能会在 DEF 以前执行,具体看实际的线程获取的CPU时间片的分配。post
可是,若是未进行程序同步,因为顺序一致性模型要求线程的操做具备原子性,也就说线程的任何操做都是立刻对其它线程可见的。因此,即便代码没有进行线程同步,多个线程看到的代码执行的顺序也是一致。优化
顺序一致性,保证程序的执行顺序一致,JMM会根据必定规则(好比遵循happens-before原则),会对程序执行指令进行重排序,达到对编译器和处理器优化的目标。在JMM模型下,在不影响程序执行结果的前提下,编译器、处理器会对指令进行重排序。关于重排序已经分析过,能够阅读这篇文章:深刻讲解并发编程模型之重排序篇spa
如图所示基于顺序一致性模型和JMM模型下,在进行线程同步时程序的执行顺序。在顺序一致性模型下,每个线程程序执行顺序已经肯定,可是在JMM模型下,每个线程在临界区的程序执行的顺序未知(虚线框起来的是临界区代码),由于JMM进行了指令重排。线程
这篇文章讲到这里,已经和你们分析完了并发模型中的一致性问题。实际上,一致性模型咱们不多用,由于这样编译器和处理器没法对程序作到优化,在Java中咱们使用的是能够进行指令重排序的JMM模型。blog
还有一个缘由,前面说过,顺序一致模型要求线程的每个操做都具备原子性,也就是说,读写都会操做主存,这样的效率确定会比JMM模型下先对线程本地内存操做的方式要低的多。