当前位置: 首页 > news >正文

湖南省城乡建设厅网站语言做网站

湖南省城乡建设厅网站,语言做网站,平顶山网站开发,google地图嵌入网站0.引言 理解 JMM (Java Memory Model - JMM) 是掌握 Java 并发编程的关键#xff0c;它定义了多线程环境下#xff0c;线程如何与主内存以及彼此之间交互内存数据。 核心目标#xff1a; JMM 旨在解决多线程编程中的三个核心问题#xff1a; 原子性 (Atomicity)#xf…0.引言 理解 JMM (Java Memory Model - JMM) 是掌握 Java 并发编程的关键它定义了多线程环境下线程如何与主内存以及彼此之间交互内存数据。 核心目标 JMM 旨在解决多线程编程中的三个核心问题 原子性 (Atomicity) 一个操作是不可中断的要么全部执行成功要么完全不执行。可见性 (Visibility) 一个线程修改了共享变量的值其他线程能够立即得知这个修改。有序性 (Ordering) 程序执行的顺序可能和代码编写的顺序不一致指令重排序JMM 定义了在何种情况下这种重排序是被允许或禁止的。 1.第一层浅显易懂 - 为什么需要 JMM (The Problem) 想象一下一个简单的场景 public class VisibilityProblem {private static boolean flag false; // 共享变量private static int value 0; // 共享变量public static void main(String[] args) {// 线程 Anew Thread(() - {while (!flag) { // 循环检查 flag// 空循环等待 flag 变为 true}System.out.println(Value: value); // 打印 value}).start();// 线程 Bnew Thread(() - {value 42; // 步骤 1设置 valueflag true; // 步骤 2设置 flag}).start();} }直觉期望 线程 B 先设置 value 42然后设置 flag true。线程 A 看到 flag 变为 true 后跳出循环打印出 Value: 42。现实问题 可见性问题 线程 B 修改了 flag 和 value但这些修改可能只存在于线程 B 的 CPU 缓存或寄存器中没有立即写回主内存。线程 A 在自己的缓存中看到的 flag 可能仍然是 false导致它永远无法跳出循环。即使跳出了循环它看到的 value 也可能是 0 而不是 42。有序性问题 编译器或处理器为了优化性能可能会对指令进行重排序。线程 B 中的 flag true 操作可能在 value 42 之前执行。如果此时线程 A 看到了 flag 为 true 而跳出循环它看到的 value 就可能是未初始化的 0。 JMM 就是为了解决这类在多线程环境下因缓存、指令重排序等优化带来的不可预测行为而制定的规则。 2.第二层核心概念 - JMM 的抽象模型 (The Abstraction) JMM 定义了一个抽象的内存模型它屏蔽了底层硬件的具体实现细节如 CPU 缓存、缓存一致性协议为 Java 程序员提供了一个统一的视图 主内存 (Main Memory): 存储所有共享变量实例字段、静态字段、数组元素的原始值。是线程间共享的区域。 工作内存 (Working Memory / Local Memory): 每个线程都有自己的工作内存。存储该线程使用到的共享变量的副本。线程对共享变量的所有操作读取、赋值等都必须在工作内存中进行不能直接读写主内存。工作内存是 JMM 的一个抽象概念它涵盖了 CPU 寄存器、各级缓存、写缓冲区等硬件优化。 内存交互操作 (8 种原子操作) JMM 定义了 8 种原子操作来描述线程、工作内存和主内存之间的交互 lock (锁定)作用于主内存变量标识其为线程独占状态。unlock (解锁)作用于主内存变量释放锁定状态。read (读取)作用于主内存变量将变量值从主内存传输到线程的工作内存。load (载入)作用于工作内存变量将 read 操作得到的值放入工作内存的变量副本中。use (使用)作用于工作内存变量将变量值传递给执行引擎如进行计算。assign (赋值)作用于工作内存变量将执行引擎接收到的值赋给工作内存变量。store (存储)作用于工作内存变量将变量值从工作内存传输到主内存。write (写入)作用于主内存变量将 store 操作传输过来的值放入主内存变量中。 规则 JMM 规定这些操作必须满足特定的顺序和约束如 read 和 load、store 和 write 必须成对按顺序出现但允许在成对操作之间插入其他操作这是导致可见性和有序性问题的根源之一。更关键的规则体现在 happens-before 原则上。 3.第三层关键机制 - Happens-Before (HB) happens-before 是 JMM 的核心概念它定义了两个操作之间的偏序关系。如果操作 A happens-before 操作 B那么 可见性保证 A 对共享变量的修改结果一定对 B 可见。有序性保证 A 在程序顺序上一定排在 B 之前执行禁止某些重排序。 注意 happens-before 并不一定意味着时间上的先后它强调的是可见性和顺序的保证。如果两个操作之间没有 happens-before 关系JVM 可以随意对它们进行重排序。 3.1JMM 定义的天然 Happens-Before 规则 程序次序规则 (Program Order Rule) 在同一个线程中按照控制流顺序可能是分支、循环等前面的操作 happens-before 后面的操作。管程锁定规则 (Monitor Lock Rule) 一个 unlock 操作 happens-before 于后续对同一个锁的 lock 操作。volatile 变量规则 (Volatile Variable Rule) 对一个 volatile 变量的写操作 happens-before 于后续对这个变量的读操作。线程启动规则 (Thread Start Rule) Thread.start() 调用 happens-before 于被启动线程中的任何操作。线程终止规则 (Thread Termination Rule) 线程中的所有操作都 happens-before 于其他线程检测到该线程已经终止如 Thread.join() 返回成功或 Thread.isAlive() 返回 false。线程中断规则 (Thread Interruption Rule) 对线程 interrupt() 的调用 happens-before 于被中断线程检测到中断事件抛出 InterruptedException 或调用 isInterrupted()/interrupted()。对象终结规则 (Finalizer Rule) 一个对象的初始化完成构造函数执行结束happens-before 于它的 finalize() 方法的开始。传递性 (Transitivity) 如果 A happens-before B且 B happens-before C那么 A happens-before C。 happens-before 的意义 程序员只需要利用这些规则主要是通过 synchronized、volatile、final 等关键字以及 java.util.concurrent 包中的工具就能确保多线程操作的可见性和有序性无需关心底层复杂的缓存和重排序细节。 4.第四层深入剖析 - volatile 关键字 volatile 是 JMM 中最重要的关键字之一它提供了比 synchronized 更轻量级的同步机制。 4.1volatile 的语义 保证可见性 对一个 volatile 变量的写操作会立即刷新到主内存。对一个 volatile 变量的读操作会从主内存中读取最新的值或保证看到最近写入的值。这通过禁止编译器/处理器对 volatile 变量的读写操作进行缓存优化来实现。 禁止指令重排序 (部分) 编译器在生成字节码时会在 volatile 写操作前后插入写屏障 (StoreStore StoreLoad)。在 volatile 读操作前后插入读屏障 (LoadLoad LoadStore)。写屏障 (Store Barrier): StoreStore: 确保在该屏障之前的所有普通写操作都刷新到主内存对其他线程可见。StoreLoad: 确保在该屏障之前的 volatile 写操作都完成并且刷新到主内存后才能执行该屏障之后的 volatile 读/写操作开销较大通常由 StoreLoad 承担。 读屏障 (Load Barrier): LoadLoad: 确保在该屏障之后的所有读操作普通读或 volatile 读都在该屏障之后的读操作之前执行禁止重排序并且强制从主内存或最新缓存中加载数据。LoadStore: 确保在该屏障之后的所有写操作都在该屏障之后的写操作之前执行禁止重排序并且这些写操作的数据依赖在该屏障之前的读操作已完成。 这些屏障共同作用确保了 volatile 变量读写操作相对于其前后代码的相对顺序从而实现了 happens-before 规则中的有序性保证。 4.2volatile 的局限性 不保证原子性 volatile 不能保证复合操作的原子性。例如 volatile int count; count; 这个操作 (count 包含读-改-写三步) 在多线程下仍然是不安全的。需要使用 synchronized 或 AtomicInteger 等。 4.3volatile 的典型用法 状态标志位 如开头的例子用 volatile boolean flag; 来安全地通知其他线程状态改变。一次性安全发布 (One-Time Safe Publication) 利用 volatile 写操作的 StoreStore 屏障确保在发布对象引用之前对象的初始化已经完全完成构造函数结束。public class Singleton {private static volatile Singleton instance; // volatile 保证安全发布private Singleton() {}public static Singleton getInstance() {if (instance null) { // 第一次检查 (无锁)synchronized (Singleton.class) {if (instance null) { // 第二次检查 (加锁)instance new Singleton(); // volatile 写}}}return instance;} }如果没有 volatile其他线程可能看到一个未初始化完成的 Singleton 对象指令重排序导致引用赋值在构造函数完成之前发生。独立观察 (Independent Observation) 定期发布观察结果供其他程序使用。开销较低的读-写锁策略 当读远多于写时可以用 volatile 保证写操作的可见性读操作不需要加锁但写操作需要额外的同步机制如 synchronized 或 CAS 来保证原子性。 5.第五层JMM 与并发编程实践 理解 JMM 对于编写正确、高效、可预测的并发程序至关重要 优先使用高级并发工具 java.util.concurrent 包 (ConcurrentHashMap, ExecutorService, CountDownLatch, CyclicBarrier, AtomicXxx 类等) 是构建在 JMM 基础之上的它们通常比直接使用 synchronized 和 volatile 更安全、更高效、更易用。理解 JMM 能让你更好地理解和使用这些工具。正确使用 synchronized synchronized 块不仅提供互斥原子性也提供强大的内存语义进入 synchronized 块获得锁相当于执行一个 volatile 读操作能看到之前持有该锁的线程的所有修改退出 synchronized 块释放锁相当于执行一个 volatile 写操作将修改刷新到主内存。这确保了临界区内外操作的可见性和有序性。理解 final 字段 被 final 修饰的字段在构造函数中初始化后其值对其他线程是可见的无需同步前提是对象的引用本身是正确发布的例如通过 volatile 或 synchronized 安全发布规则。这是 JMM 对 final 的特殊保证。避免过度同步 不必要的同步会带来性能开销。理解 JMM 可以帮助你判断何时需要同步主要是为了保护共享可变状态何时可以避免。警惕内存可见性导致的微妙 Bug 很多并发 Bug 不是由竞态条件引起的而是由内存可见性问题引起的。理解 JMM 是诊断这类 Bug 的基础。 6.总结 JMM 是什么 一个规范定义了多线程环境下 Java 程序如何与内存交互确保程序在并发执行时的可见性、有序性以及通过其他机制如锁保证的原子性。核心问题 解决因 CPU 缓存、指令重排序导致的可见性和有序性问题。抽象模型 主内存共享和工作内存线程私有副本定义了 8 种内存交互操作。核心机制 happens-before 关系。它定义了操作间的可见性和顺序保证。JMM 定义了一系列天然规则程序次序、锁、volatile、线程启动/终止等。volatile 关键字 保证可见性写立即刷新读获取最新值。通过内存屏障StoreStore, StoreLoad, LoadLoad, LoadStore禁止特定类型的指令重排序。不保证原子性。 实践意义 理解 JMM 是编写正确、高效并发 Java 程序的基础。它解释了高级并发工具的工作原理指导你正确使用 synchronized、volatile、final并帮助你诊断复杂的并发 Bug。 掌握 JMM 需要时间和实践。从理解基本问题和抽象模型开始逐步深入到 happens-before 和 volatile 的细节最终将其应用于并发编程实践中是学习 JMM 的有效路径。
http://www.hkea.cn/news/14367032/

相关文章:

  • 快速进入网站如何开发自己的小程序
  • 网站放到服务器短链接生成二维码
  • 接项目做的网站网络黄页推广软件哪个好
  • 云南网站设计联系方式创办一个网站需要多少资金
  • 免费手机网站源码下载做实验的网站
  • 婚庆企业网站建设cookie做网站访问量
  • 荣耀手机商城官方网站荣耀60pro怎么做家政的网站
  • 响应式环保网站二维码引流推广的平台
  • 做网站怎么删除图片seo是什么职业
  • 做企业网站代码那种好怎么设置网页版浏览器
  • 优秀网站设计案例中国网站建设管理典型经验材料
  • 旅游做哪个网站好wordpress 编辑
  • 企业网站的基本类型包括苏州网站建设网
  • 支付网站建设费的会计分录照片生成视频制作软件
  • 制作公司网站设计要求广东住房和城乡建设厅官方网站
  • 织梦官方网站网站导航优化
  • wordpress做个米表搜索引擎排名优化亚当
  • 企业网站建设需求调查lol视频网站模板
  • 网站建设 应该付多少维护费呢建设网站模版
  • 顺德营销网站设计wordpress自定义页面插件
  • w3c网站代码标准规范上海哪里做网站好
  • 装修门户网站程序 cms寿县网站建设
  • 网站开发主要语言WordPress积分提现插件
  • 游戏公司网站模板网页制作类软件有哪些
  • 网站下载软件入口住房城乡建设网站藁城
  • 网站建设上的新闻一个app网站
  • 怎么自己做一个网站关键词优化包年推广
  • seo网站建站公司的主页江苏省交通工程建设局网站
  • 手机建设银行网站个人如何接外贸订单
  • 东营建网站公司网页设计空格代码快捷键