详细分析Java内存模型的完整攻略
Java内存模型(Java Memory Model,JMM)是Java虚拟机(JVM)创造的一种抽象概念,用于规范Java程序在内存中的行为。因为Java程序是运行在虚拟机中,虚拟机又是运行在操作系统中,所以Java程序在内存中的表现是比较复杂的。Java内存模型对Java程序在内存中的访问和修改行为做了明确的规范,确保Java程序在不同的平台上能够一致地表现。
Java内存模型的基本概念
Java内存模型的基本概念包括:
- 主内存(Main Memory):Java程序访问的共享内存,JVM中所有线程都可以访问它。
- 工作内存(Working Memory):Java程序中每个线程独有的内存空间,线程执行时将主内存中的共享变量复制到工作内存中进行操作,操作完成后再写回主内存。
- 对象锁(Object Monitor):Java程序中一个对象可以用于同步的机制,线程可以通过竞争对象锁来获取对共享变量的访问权。
Java内存模型的规范
Java内存模型通过一些规范确保Java程序在内存中能够正确表现:
- 原子性:Java内存模型保证变量的读取和写入操作是原子的,即一个线程的写操作对于其他线程的读操作是同步可见的。
- 可见性:Java内存模型保证变量的写入操作对其他线程是可见的,即一个线程的写操作对于其他线程的读操作是同步可见的。
- 有序性:Java内存模型保证变量的读取和写入操作是有序的,即一个线程的写操作不会被重排序到对其他线程的读操作之后。
Java内存模型的示例
示例1:原子性
public class AtomicTest {
private static volatile int count = 0;
public static void main(String[] args) throws InterruptedException {
for(int i=0;i<10;i++){
new Thread(() -> {
for(int j=0;j<1000;j++){
count++;
}
}).start();
}
Thread.sleep(3000);
System.out.println("count:"+count); // 可能输出小于10000的数字
}
}
在上面的代码示例中,定义了一个静态变量count,同时创建了10个线程对它进行操作,每个线程循环执行1000次count的自增操作。在程序最后,输出count变量的值。由于count变量的自增操作不是原子的,因此最终输出的count的值可能小于10000。
为了解决这个问题,可以使用JDK中提供的原子类,例如AtomicInteger。
示例2:可见性
public class VisibilityTest {
private static volatile boolean flag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
while(!flag){
// do something
}
System.out.println("Done!");
}).start();
Thread.sleep(1000);
flag = true;
}
}
在上面的代码示例中,定义了一个静态变量flag,并创建了一个线程不断循环执行直到flag变为true,然后输出Done!的信息。在主线程中,将flag变量赋值为true。
由于flag变量没有被volatile修饰,其写入操作在主线程的工作内存中完成,并没有及时写回主内存中,因此在另一个线程中flag变量的值可能为false,导致线程一直在循环执行。
为了解决这个问题,可以给flag变量添加volatile修饰符,确保写入操作能及时写回主内存中。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详细分析Java内存模型 - Python技术站