当前位置: 首页 > 网络应用技术

JMM和顺序模型与Hapens-Before Model之间的关系和差异

时间:2023-03-07 11:34:54 网络应用技术

  本文详细介绍了Java存储器模型,顺序一致性存储器模型和原始Hapens-Be Fore Memory模型之间的差异和连接。

  Java内存模型的设计是指订单一致性内存模型和原始的Hapens-Be Memory模型,该模型吸收了它们的优势并改善了其缺点。

  在多线程中,当程序未正确同步时,将存在数据竞争。在另一个线程中读取相同的变量;而且写作和阅读不是通过同步排序的!

  当代码包含数据竞赛时,该程序的执行通常会生成违反直觉的结果(上一章的示例完全是这种情况)。如果可以正确同步多线程,则该程序将是一个程序没有数据竞争。

  JMM为正确和同步的多线程程序的内存一致性提供以下保证:

  如果程序正确同步,则程序执行将具有顺序一致的 - 即该程序的执行结果与顺序内存模型中程序一致性的执行结果相同。

  此处的同步是指广义上的同步,包括正确使用常用的同步原语(锁定,挥发性和最终)。LET查看顺序一致性存储器模型。

  顺序一致性记忆模型是一个理论参考模型,由计算机科学家理想化。在程序执行过程中,它是可见性和序列的有力保证。设计时,内存模型和处理器内存模型的存储器模型将基于订单一致性内存模型。

  订单一致性内存模型有两个主要特征:

  顺序一致性内存模型为观众提供如下:

  在概念上,顺序一致性模型具有单个全局内存。该内存可以通过带有左右开关的开关连接到任何线程。同时,每个线程必须按照程序顺序执行内存读取/写作操作。在任何时间点,只能连接一个线程与内存。执行多个线程后,交换设备可以读取序列化/写入所有线程的操作。

  假设这两个线程使用监视器锁正确同步:螺纹A的三个操作后释放监视器锁,然后螺纹B获得相同的监视器锁定。

  现在假设这两个线程没有同步。以下是该未分解程序的执行图,以一致性模型:

  尽管总体执行顺序在顺序一致性模型中是无序的,但所有线程只能看到一致的总体执行顺序:上面的数字是示例。线程A和B看到的执行顺序是:B1-> A1-> A2-> B2-> A3->B3。可以获得此保证的原因是因为必须在顺序一致的存储器模型中看到每个操作任何线程立即。

  但是,在JMM.M.中,不能保证总体执行顺序在JMM中是无序的,但是所有线程的操作顺序可能不一致。例如,在当前线程中,已写入本地内存中的书面数据仅在当前线程刷新到主内存之前可见。

  从其他线程的角度来看,将考虑到当前线程尚未执行此写作操作。仅在当前线程刷新本地内存中的数据之后,可以看到此写作操作的其他线程可见在这种情况下,当前螺纹和其他线程的操作的操作顺序将不一致。

  在上面的示例代码中,假设螺纹执行writer()方法后,reader()方法是由线程执行的。这是正确且同步的多线程program.cording occording符合JMM规范,则执行结果该程序将与顺序一致模型中过程的执行结果相同。以下是两个内存模型中程序的执行时间的比较图表:

  在顺序的一致性模型中,所有操作均按照程序的顺序串行执行。,这将破坏显示器的语义).JMM将在出口监视器的两个关键时间点上进行一些特殊处理,并进入监视器,因此线程在这两个时间点上具有相同的连续模型的内存视图(在特定细节之后解释)。尽管线程A在关键区域已经排序,但由于监视器的相互排斥执行的特征,这里的线程B无法“观察”到螺纹A在关键区域中的重分类。大量排序不仅提高了执行效率,而且不会改变程序的执行结果。

  从这里我们可以看到JMM在特定实现中的基本原理:在过程的执行结果的前提下,没有更改(正确同步)程序,即尽可能多地优化编译器和处理器的门。

  对于未同步或未正确同步的多线程程序,JMM仅提供最小的安全性:在线程执行过程中读取的值,要么由线程编写的值或默认值(0,null,false)JMM保证该值线程读取操作的价值不会从稀薄的空气中出现。为了达到最低的安全性,当JVM分配在堆上时,将首先清除零存储空间,然后将对象分配(上面)(这两个操作将在JVM内部同步)。因此,当域分配时,域的默认初始化已完成。

  JMM不能保证未分解程序的执行结果与程序一致模型的执行结果一致。由于未准备好的程序是按顺序一致性模型执行的,整体顺序是无序的,并且无法预测执行结果。。确保两个模型中UNSMOCHROMA的执行结果毫无意义,这是毫无意义的。

  像顺序一致性模型一样,当jmm中执行前所未有的程序时,它也是无序的,并且无法预测其执行结果。在同一时间,在这两个模型中,无抵押程序的执行特性存在几个差异:

  原始模型的原始模型太弱了。所有Java内存模型都允许行为,也允许Hapens模型,但是Java存储器模型不允许某些行为,例如违反了难以捉摸的方式违反因果关系,使某种数量的值出现在稀薄的空气中。。如下所示:1:

  作为上述代码,以正确和同步的原始HAPEN-BE前内存模型,执行结果是R1 = R2 = 1的情况。

  这会导致不可能的结果R1 = R2 = 1。

  当写作操作在依赖操作之前发生时,我们将此问题称为因果关系他们看。

  Java内存模型使用特定的执行过程和程序作为输入,然后确定执行过程是否是程序的法律执行。它是通过逐渐建立一组“提交”操作来实现的,这些操作反映了我们知道的哪些动作可以通过程序执行而无需“因果周期”。

  通常,要提交的下一个动作是可以以同一顺序执行的下一个动作。但是,为了证明阅读操作可以看到程序序列中其他线程的值,我们允许一些操作提交在较早发生的其他动作之前。

  Java存储器模型允许下图2中的行为,即使此示例似乎具有周期因果关系。然后最终将4:B = 2移至正面。这对编译器的性能非常有帮助。

  可以提前提交一些操作,而其他操作则不能提交。Java内存模型不允许图1中的R1 = R2 = 1的初始情况,但是允许图2的替换情况。Java内存模型将确定某个操作的发生不会引起数据纠纷,并且允许该诉讼提前提交。

  SO称为数据竞赛(数据竞赛),简单的解释是:一个线程中有一个写作操作,另一个线程读取此书面变量值,并且不同时对读取和写作操作进行分类。发生,称为数据争议。

  对于图1,因为我不知道数据X的值,所以Java内存模型不允许在阅读前进行写作操作;对于图2,似乎是JVAV内存模型。尽管我不知道A,R1 == R2的值始终是正确的,因此可以优化!

  顺序一致性内存模型对于Java来说太严格了,不适合Java内存模型,因为它禁止标准编译器和处理器优化并影响性能。该模型非常接近Java内存模型的需求,但是它太弱了,允许允许违反因果关系的不可接受的事物。这是针对Java内存模型,而ProgramMersit是不可接受的。因此,Java使用改进的内存模型 - 形成自己的低迷模型,即JMM。

  关于JMM和改进的内存模型,可以详细说明本文:详细说明Java内存模型和Hapens-原理。

  参考资料: