Java内存模型(JMM)是 Java 虚拟机的一个重要部分,用于管理程序中的内存访问。JMM定义了线程间共享内存的访问规则,确保了内存可见性和原子性,并防止了竞争条件。
JMM的主要内容包括以下几点:
1)可见性:线程间共享内存的可见性,确保了线程间的信息可以互相可见。
2)原子性:确保了内存访问操作是原子操作,即不可中断。
3)有序性:确保了内存访问操作的顺序。
JMM通过使用同步、锁和 volatile 变量等技术来实现上述规则。使用同步和锁可以保证内存访问的互斥性,从而确保可见性和原子性;使用 volatile 变量可以保证变量的可见性。
通过遵循 JMM 的规则,开发人员可以保证程序的正确性和可靠性,同时避免常见的内存问题,如竞争条件、死锁等。
1、volatile 可见性的实现原理
java中的volatile关键字可以保证变量的可见性。它的实现原理是通过内存屏障和禁止重排序优化来实现的。
1)内存屏障:内存屏障是一种特殊的指令,用于控制处理器缓存中的数据和内存的同步。内存屏障会强制处理器在执行该指令前写回缓存中的数据,并在执行该指令后从内存中读取数据。
2)禁止重排序优化:禁止重排序优化是处理器在执行代码时所做的一种优化,其目的是提高代码的执行效率。在使用volatile关键字修饰的变量被修改时,编译器和处理器都会插入内存屏障指令,从而禁止重排序优化。
当多个线程共享一个volatile变量时,任何一个线程对该变量的修改,都会立刻被其他线程看到。这是因为,当一个线程修改了该变量时,会强制将缓存中的数据写回内存,同时禁止重排序优化,从而保证了其他线程在读取该变量时读取的是最新的数据。
总的来说,volatile关键字通过内存屏障和禁止重排序优化,确保了多个线程间共享变量的可见性。使用volatile关键字的变量在读取和修改操作时不会被缓存,而是直接从内存中读取或写入,从而确保了数据的一致性。
但是,请注意,使用volatile关键字仅仅保证了变量的可见性,并不能保证原子性。如果你需要保证变量的原子性,则可以使用Java的原子类或者同步机制。
另外,volatile关键字还有一个缺点,就是性能比较低。因为它的每次读取和修改操作都要直接从内存中读取或写入,从而造成了大量的内存读写操作,降低了程序的执行效率。因此,使用volatile关键字的地方要适当,不能滥用。