- JMM:提供了统一的视图
- 提供了很多关键字做到按需禁用缓存+按需禁用编译优化
a. final
b. sync
c. volatile
并发编程一直是软件开发中的一个挑战性领域,Java 作为一门成熟的编程语言,在并发处理方面提供了丰富的机制和工具。本文旨在探讨 Java 是如何解决并发问题的,特别是通过 Java 内存模型(JMM)以及提供的关键字如 final、synchronized 和 volatile。
1. Java 内存模型(JMM)
Java 内存模型(JMM)是解决并发问题的基石,它定义了线程和主内存之间的抽象关系。JMM 处理了多线程环境中变量的可见性、原子性以及有序性问题,确保了并发下的一致性和线程安全。
可见性
可见性指的是当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。JMM 通过 volatile 关键字保证了变量的可见性。当变量被声明为 volatile 后,对它的写操作将会立即同步到主内存中,对它的读操作将会直接从主内存中读取。
原子性
原子性指的是一个或多个操作完全由当前执行它们的线程执行,中间不会被其他线程打断。JMM 通过 synchronized 关键字来保证方法和代码块的原子性。当一个线程访问同步代码块时,它会锁定这个代码块的对象,直到线程执行完毕释放锁,其他线程才能访问。
有序性
有序性指的是程序执行的顺序按照代码的先后顺序执行。JMM 中,volatile 和 synchronized 关键字同样可以保证有序性。volatile 变量的读写操作不会被编译器重排序,synchronized 块内的代码在执行时也会保证按照顺序执行。
2. 关键字
Java 提供了多种关键字来帮助开发者按需进行并发控制,包括禁用缓存以及禁用编译器优化等。
final
final 关键字可以确保对象一旦被初始化后其值就不可改变。对于引用类型,final 保证引用不会改变,但是对象的状态(即内容)可以改变。这对于创建不可变对象以及确保对象发布的安全性非常有用。
synchronized
synchronized 关键字可以修饰方法或代码块,保证同一时刻只有一个线程能执行该代码块。它保证了临界区的互斥访问,以及进入和退出临界区时变量的同步更新到主内存,从而解决了原子性和可见性问题。
volatile
volatile 关键字保证了变量的可见性和部分有序性。对 volatile 变量的写操作会立即反映到主内存,对其的读操作会直接从主内存读取。这避免了变量在本地线程内存中的缓存,使得一个线程对这个变量的修改对其他线程是可见的。然而,volatile 不保证操作的原子性。