Java内存模型是一个规定了线程之间如何通过内存进行通讯的规范。JMM(Java Memory Model)规定了Java虚拟机如何控制线程与内存之间的数据传输。JMM主要通过定义内存栅栏和Happens-Before规则来实现线程通信。
JMM内存栅栏
内存栅栏是指一种同步屏障,用于强制共享数据的可见性和顺序性,确保各线程对内存所读到的数据是一致的。
Load/Store屏障
Load/Store屏障的主要目的是确保读和写的顺序。例如,代码中a=1;b=a;如果读写没有顺序,则b可能是0,而不是1。
Read/Write屏障
Read/Write屏障的作用是确保变量的可见性。每当执行一个读或写操作时,都要通过读屏障或写屏障来确保变量在所有线程之间是一致的。
JMM Happens-Before规则
Happens-Before规则是指若两个操作存在Happens-Before关系,则第一个操作的执行结果对第二个操作可见,即第一个操作的结果影响第二个操作的结果。
程序顺序规则
Program Order Rule指在同一个线程中,按写一个变量的语句在时间上排在读语句之前。
监视器锁规则
Monitor Lock Rule指对一个锁的解锁操作必须在对这个锁的加锁操作之前执行。
volatile变量规则
Volatile Variable Rule指写volatile变量的操作条件对后续读这个变量的操作可见,即前者的值对后者是可见的。
线程启动规则
Thread Start Rule指线程的start()方法必须在线程执行之前完成。
线程加入规则
Thread Join Rule指线程等待操作必须在线程执行完毕之后才能完成。
线程中断规则
Thread Interruption Rule指调用Thread.interrupt()方法必须先于被中断线程的处理中断信号操作。
对象终结规则
Finalizer Rule指某个对象的初始化必须在线程启动之前完成,某个对象的finalize()方法必须在对象被终结之前完成。
使用示例1:
public class VolatileTest {
private static volatile int value = 0;
public static void main(String[] args) {
new Thread(() -> {
while (value == 0) {}
System.out.println("Value is changed to: " + value);
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
value = 1;
}
}
上述代码使用了volatile变量规则,确保了线程中value的值能够被其他线程正确读取。
使用示例2:
public class HappensBeforeTest {
private static int a = 0;
private static int b = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
a = 1;
b = a;
});
Thread t2 = new Thread(() -> {
System.out.println("a = " + a + ", b = " + b);
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
上述代码中,使用Happens-Before规则,确保线程t2能够正确读取线程t1中写的变量a和b的值。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:什么是Java内存模型? - Python技术站