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

让我们一起学习并发编程:Java内存模型(3)顺序一致性

时间:2023-03-06 13:55:47 网络应用技术

  介绍:

  序列一致性存储模型是理论参考模型。内存模型和处理器内存模型和编程语言的内存模型将基于订单一致性内存模型。

  当程序未正确同步时,可能会有数据竞争。

  1.1 JAVA内存模型规范数据竞争的定义如下。如果可以正确同步多线程程序,则该程序将是一个没有数据竞争的程序。通常有数据竞争程序。操作结果将与我们的预期结果有偏差。

  1.2 JMM,以确保多线程程序的内存一致性。如果程序正确同步(同步,波动性和最终),则该程序的执行将是一致的 - 也就是说,该程序的执行结果在一致性内存模型中的执行结果是相同的。

  2.1功能图标:

  序列一致性内存模型视图

  在概念上,顺序一致性模型具有单个全局内存。该内存可以通过带有左右开关的开关连接到任何线程。同时,每个线程必须按照程序顺序执行内存读/写操作。在上图中可以看到一个线程,任何时候只能连接到内存。同时执行,图中的开关设备可以读取所有内存读/写操作的序列化(即,顺序一致性模型中的所有操作都具有完整的订单关系)。

  2.2示例描述物质一致性模型假设执行两个线程A和B。

  线程A在程序中的操作顺序为:A1 -A2 -A3

  该程序中线程B的操作顺序为:B1 -B2 -B3。

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

  物质一致性模型执行效果

  假设线程A和线程B没有同步,则在顺序一致性模型中未经判断的程序的前所未有的程序如下:

  订单一致性模型的另一个执行效果

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

  但是,在JMM.M.中,不仅保证总体执行顺序在JMM中是无序的,但是所有线程的操作顺序可能不一致。在刷新主内存之前,本地记忆只能看到当前线程的写作操作。从其他线程的角度观察,将考虑到此写作操作从根本上是由当前线程编写的。Implement.ly在当前线程刷新本地内存中的数据之后,该数据写入主存储器中,可以看到此写作操作到其他线程。在这种情况下将有各种各样的操作结果。

  2.3同步程序订单一致性效应与上一章中的ReseRverExample程序的锁同步

  测试代码

  多个结果的结果为1

  总结

  在上面的示例代码中,假设执行A Writer()方法后,B线程执行reader()方法。这是正确且同步的多线程program.cording to jmm规范,则执行结果。程序将与程序一致的内存模型的执行结果相同。

  JMM存储器模型中的物质一致性模型和执行时间序列图

  总结

  在顺序的一致性模型中,所有操作均按照程序的顺序串行执行。,这将破坏监视器锁的语义).JMM将在进入关键区域并退出关键区域的关键时间点上进行一些特殊处理两个时间点。尽管A线A在关键区域进行了沉重的分类,这是由于监视锁的特征,线程B无法“观察”螺纹A在关键区域的重分类。JMM的基本原理具体的实现是:不更改(正确的同步)程序执行结果,尽可能优化编译器和处理器优化。

  2.4无抵押程序的执行特性未同步或未正确同步(撰写错误的代码的兄弟),JMM仅提供最低安全性:

  线程中读取的值不会是不可预测的(稀薄的空气)

  在两个模型中的无抵押程序的执行特性的比较

  单线程订单执行√√×一致的操作执行顺序√×64 -bit Long和double -type变量写入原子√×与总线机构相关的第三个差异。在大约32位 - 位处理器,处理64-位数据编写操作中需要进行64位数据编写操作分为两个32位写作操作。

  3.1 CPU,内存和总线在计算机中简要描述,数据在处理器和内存之间通过总线传递。处理器和内存之间的数据传输由一系列步骤完成。此Seriesthe步骤称为总线交易。总线交易包括读取事务和写入术,它将在内存中读写一个或多个物理连续单词。

  阅读交易→记忆到处理器

  写入交易→处理器到内存

  关键是,总线将同时尝试使用总线的业务。在处理器执行总线交易中,总线将禁止其他处理器和IO设备读取和写内存。

  数字:

  公交工作机制

  如上图所示,假设处理器A,B,C和D同时将总线交易启动到总线。确保所有处理器都可以公平访问内存)。这次,处理器A继续其总线交易和所有其他总线交易必须等待A的交易再次完成内存的读写操作。总线交易工作机制可确保处理器的访问以串行方式执行。在任何时间点,只有一个可以访问内存的处理器。此特征确保了总线交易之间的内存读写操作具有原子性。

  3.2大约32位处理器上的长和双型操作。如果要求对64位数据进行原子写作操作,则将有一个非常大的同步开销。Java语言规范鼓励但不强迫JVM编写64位 - 位长和双重类型的可变写作操作。当JVM在此处理器上运行时,将将64位变量的写入操作删除为两个32位写作操作。目前,写作没有原子性。

  数字:

  公交交易执行的定时图

  现有问题:

  假设处理器A编写一个长的长变量,同时,处理器B读取了此长类型变量。处理器A中的64位写作操作分为两个32 -bit的写作操作,而两个32- 标签写操作分配给不同的交易。这次,将处理器B的64位阅读操作分配给单个读取事务。如果上面的执行顺序,则处理器B读取不完整的无效值。

  处理方法:

  JSR-133内存模型启动(JDK1.5)。写作操作可以分为两项32位写作交易。读取操作必须在单个交易中执行。

  文章总结了“ Java并行编程艺术”,下一篇文章总结了“挥发性记忆症状”,因此请继续关注。