JMM中保证了一些基本操作的原子性,例如读取和写入基本类型变量的操作。以下是一个示例说明JMM的原子性:
假设有两个线程t1和t2,它们同时对一个变量x进行自增操作。代码如下:
public class Main {
public static int x = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000000; i++) {
x++;
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000000; i++) {
x++;
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
}
在这个示例中,两个线程t1和t2同时对变量x进行自增操作,每个线程自增1000000次。根据预期,程序应该输出2000000。然而,由于线程间的竞争关系,实际的输出结果可能会小于2000000。
如果没有JMM的原子性保证,线程t1和t2可能会同时读取x的值,然后都对其进行自增操作,导致x的值只增加1,而不是2。这就是典型的“竞态条件”(Race Condition)问题。
但是,由于JMM保证了对基本类型变量的读取和写入操作是原子的,所以线程t1和t2的自增操作会分别读取x的当前值,执行自增操作,然后将结果写回x。这样,即使t1和t2同时访问变量x,也不会发生竞态条件问题,程序的输出结果将会是正确的。
因此,JMM的原子性保证了对基本类型变量的读取和写入操作是原子的,从而避免了线程间的竞态条件问题,保证了程序在多线程环境下的正确性。