Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范中定义的一种关于内存访问、共享变量在多线程之间的可见性、以及原子性、顺序性的规则。Java内存模型的目标是定义程序中各个共享变量的访问方式,以及如何在并发情况下保证这些访问的正确性。
在Java中,每个线程都有自己的工作内存(Work Memory),这些工作内存是线程私有的,保存了被线程使用的变量的副本。而主内存(Main Memory)则是所有线程共享的,其中保存了共享变量的实际值。
当线程需要读取或修改共享变量时,它首先会在自己的工作内存中操作这个变量的副本,然后再将修改后的值同步回主内存。同样,当线程需要读取共享变量的值时,它会先从主内存中读取最新的值到自己的工作内存中。
Java内存模型通过Happens-Before规则来定义这些操作的可见性和顺序性。这些规则确保了某些操作在并发环境下是可见的,并且保证了操作的顺序性。
下面是一个简单的Java内存模型的例子:
public class VisibilityExample {  
     private static boolean ready;  
     private static int number;  
   
     public static void main(String[] args) throws InterruptedException {  
         Thread one = new Thread(() -> {  
             number = 42;  
             ready = true; // ①  
         });  
   
         Thread two = new Thread(() -> {  
             while (!ready) {  
                 Thread.onSpinWait(); // ②  
             }  
             System.out.println(number); // ③  
         });  
   
         one.start();  
         two.start();  
   
         one.join();  
         two.join();  
     }  
 }
 在这个例子中,线程one设置了number的值并标记ready为true。线程two在一个循环中等待ready变为true,然后打印number的值。
如果没有正确的同步机制,线程two可能看不到线程one对number和ready的修改,因为这两个线程的工作在不同的内存区域中。这可能导致线程two打印出number的初始值(0),而不是线程one设置的值(42)。
为了解决这个问题,可以使用synchronized关键字或volatile关键字来确保内存可见性。在这个例子中,如果将ready声明为volatile,则线程one对ready的修改将立即对线程two可见,从而确保线程two能够正确打印出number的值。
 private static volatile boolean ready; // 使用volatile关键字
 通过正确地使用Java内存模型提供的同步机制,程序员可以编写出在多线程环境下正确工作的并发程序。