Java内存模型

本文详细解释了Java内存模型(JMM)在并发编程中的作用,包括解决线程可见性和重排序问题,以及volatile、原子性和有序性等概念。通过工作内存与主内存的交互和happens-before原则,确保多线程程序的正确性和一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java内存模型(JMM)定义了Java虚拟机(JVM)在计算机内存中的工作方式,特别是关于共享内存的并发操作。JMM解决了两个基本问题:线程间的可见性和重排序问题。可见性指的是一个线程对共享变量修改的结果什么时候对另一个线程可见;重排序是指编译器和处理器为了优化程序性能而做的指令序列调整。

JMM的主要特点

  1. 可见性(Visibility)
    可见性保证一个线程对共享变量的修改,最终会对其他线程可见。Java提供volatile关键字来保证可见性。

  2. 原子性(Atomicity)
    原子性是指一个操作是不可中断的,即使是在多线程同时执行的情况下。在Java中,原子性主要是通过synchronized关键字和java.util.concurrent.atomic包下的原子类来实现。

  3. 有序性(Ordering)
    有序性即程序执行的顺序按照代码的先后顺序执行。Java中,volatile关键字和happens-before原则是保证操作有序性的主要手段。

JMM与工作内存和主内存交互

JMM定义了线程和主内存之间的抽象关系。线程间的共享变量存储在主内存中,每个线程都有一个私有的本地内存(工作内存),本地内存保存了该线程使用到的变量的主内存副本拷贝。

线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不是直接对主内存操作。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。

内存间交互操作

JMM定义了8种操作来完成主内存与工作内存之间的交互:

  • lock:作用于主内存的变量,它标识一个变量被某个线程独占。
  • unlock:作用于主内存的变量,它标识一个变量由锁定状态变为解锁状态。
  • read:作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中。
  • load:作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
  • use:作用于工作内存的变量,它把工作内存中的一个变量的值传递给执行引擎。
  • assign:作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量。
  • store:作用于工作内存的变量,它把工作内存中的一个变量的值传送到主内存中。
  • write:作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

这些操作必须是原子性的,不可再分的(对于readloadstorewrite来说是成对的)。

volatile关键字

volatile是JMM的关键字,用于标记Java变量,确保此变量对所有线程的可见性。volatile变量的读/写操作与锁有相似的内存语义,即每次读取时都从主内存读取,每次写入时都写入主内存。

public class VolatileExample {
    private volatile boolean active;

    public void run() {
        while (active) {
            // do something
        }
    }

    public void stop() {
        active = false;
    }
}

在上面的示例中,active变量被volatile修饰,确保了run方法中对该变量状态的读取总是从主内存中获取最新的值,而stop方法中的写入也会立即反映到主内存中。

synchronized关键字

synchronized关键字可以保证方法或代码块一次只能被一个线程执行。此外,它还能保证进入同步代码块时将变量的最新值从主内存读到工作内存中,退出时将工作内存的变量状态刷新回主内存。

public class SynchronizedExample {
    private int sharedState;

    public synchronized void increment() {
        sharedState++;
    }

    public synchronized int getSharedState() {
        return sharedState;
    }
}

在这个示例中,increment方法用于增加sharedState的值,getSharedState方法用于获取sharedState的值。由于这两个方法都被synchronized修饰,所以对sharedState的所有访问都是同步的。

happens-before原则

JMM定义了happens-before原则来确定程序中不同操作间的偏序关系:

  • 程序顺序规则(Program Order Rule)
  • 监视器锁规则(Monitor Lock Rule)
  • volatile变量规则(Volatile Variable Rule)
  • 线程启动规则(Thread Start Rule)
  • 线程终止规则(Thread Termination Rule)
  • 中断规则(Interruption Rule)
  • 终结器规则(Finalizer Rule)
  • 传递性规则(Transitivity Rule)

总结

JMM是一个抽象的概念,它定义了一个线程如何通过主内存与其他线程进行交云,以及线程如何和主内存协作从工作内存同步数据,以达到线程安全。JMM通过volatile、synchronized关键字,以及happens-before原则为程序员提供了工具和规则来编写多线程程序。

在编写多线程程序时,确保正确使用JMM的规则和提供的关键字至关重要,因为这能够帮助防止内存一致性错误,保证程序的并发性和正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

辞暮尔尔-烟火年年

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

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

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

打赏作者

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

抵扣说明:

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

余额充值