JVM之Java内存模型

Java内存模型(Java Memory Model,简称JMM)是Java虚拟机(JVM)规范中定义的一套规则,用于描述多线程环境下变量如何被访问和同步。在多线程编程中,内存模型的重要性不言而喻,它直接关系到程序的正确性和性能。本文将深入探讨Java内存模型的原理、特性、示例以及总结。

一、基本概念

1. 主内存与工作内存

  • 主内存:主内存是JVM中所有线程共享的内存区域,用于存储Java程序中的变量和对象实例等数据。所有的共享变量都存储在主内存中,包括实例字段、静态字段和数组元素等。
  • 工作内存:每个线程都有自己的工作内存,也称为本地内存。工作内存是线程私有的,用于存储主内存中共享变量的副本。线程对变量的所有操作(读取、写入)都在工作内存中进行,而不是直接操作主内存。

2. 内存交互操作

JMM定义了以下八种操作来完成主内存和工作内存之间的交互:

  • lock(锁定):作用于主内存的变量,将变量标识为一条线程独占状态。
  • unlock(解锁):作用于主内存的变量,释放处于锁定状态的变量,允许其他线程锁定该变量。
  • read(读取):作用于主内存的变量,将变量值从主内存传输到线程的工作内存中。
  • load(载入):作用于工作内存的变量,将read操作从主内存中得到的变量值放入工作内存的变量副本中。
  • use(使用):作用于工作内存的变量,将工作内存中的一个变量值传递给执行引擎。
  • assign(赋值):作用于工作内存的变量,将执行引擎接收到的值赋给工作内存的变量。
  • store(存储):作用于工作内存的变量,将工作内存中的一个变量的值传送到主内存中。
  • write(写入):作用于主内存的变量,将store操作从工作内存中得到的变量的值放入主内存的变量中。

三、特性

1. 原子性(Atomicity)

  • 定义:一个或多个操作,要么全部执行,要么全部不执行,在执行过程中不会被任何因素打断。
  • 实现方式:在Java中,对基本数据类型的访问和操作是原子的,例如对int、long、short、byte、char、boolean和reference类型的读写操作都是原子的。对于复合操作(如i++),则需要通过同步机制(如synchronized、Lock等)来保证原子性。

2. 可见性(Visibility)

  • 定义:一个线程对共享变量的修改,能够被其他线程看到。

  • 实现方式:Java内存模型通过volatile关键字和synchronized关键字来实现可见性。

    • volatile关键字:当一个变量被声明为volatile时,对该变量的读写操作都会直接作用于主内存,从而保证了可见性。但是,volatile关键字不能保证操作的原子性。
    • synchronized关键字:synchronized关键字通过锁定机制来确保只有一个线程可以执行一段代码。当一个线程访问一个对象的synchronized方法或代码块时,它将获得该对象的锁,其他线程则必须等待。在解锁之前对变量的修改对其他线程是可见的。

3. 有序性(Ordering)

  • 定义:程序执行的顺序按照代码的先后顺序执行。
  • 实现方式:Java内存模型通过Happens-Before原则来定义操作之间的偏序关系,从而允许一定程度的重排序,但同时又保证程序最终执行的结果与预期一致。

三、Happens-Before原则

Happens-Before原则是Java内存模型中定义的一组偏序关系,用于判断两个操作之间的内存可见性和有序性。它包括以下几种情况:

* 程序次序规则

一个线程中的每个操作,Happens-Before于该线程中的任意后续操作。

* 监视器锁规则

对一个锁的解锁,Happens-Before于随后对这个锁的加锁。

* volatile变量规则

对一个volatile变量的写,Happens-Before于任意后续对这个volatile变量的读。

* 传递性

如果A Happens-Before B,且B Happens-Before C,那么A Happens-Before C。

* 线程启动规则

Thread对象的start()方法调用Happens-Before于该线程的每一个动作。

* 线程终止规则

线程的所有操作都Happens-Before于其他线程检测到这个线程已经终止。

* 线程中断规则

对线程interrupt()方法的调用Happens-Before于被中断线程的代码检测到中断事件的发生。

* 对象终结规则

一个对象的初始化完成(构造函数执行结束)Happens-Before于它的finalize()方法的开始。

四、代码示例

1. 可见性示例

代码示例

public class VisibilityExample {
   
   
    private static boolean ready;
    private static int</
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾光编程

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值