Java内存模型(JMM)是一种抽象结构,描述Java程序中各线程与内存的交互方式。它规定了线程如何观察和操作共享变量,用于避免各种并发问题的发生。
JMM主要围绕三个方面进行规定:
- 原子性:要求对原子操作的执行结果,要么所有的线程都可见,要么所有的线程都不可见。
- 可见性:要求一个线程对共享变量的修改,要及时的变为其他线程可见。
- 有序性:要求程序执行的顺序按照代码的顺序执行。
要避免并发问题,我们需要:
- 使用volatile关键字:可见性,禁止指令重排序。
- 使用synchronized关键字:原子性,可见性,有序性。
- 使用Atomic包下的类: CAS机制实现原子性。
- 不可变对象:共享对象的状态不能被修改。
- 避免过长的字符串串联:会产生临时对象,破坏有序性。
- 用局部变量取代非常量的静态变量:避免可见性问题。
来看一个简单例子:
public class JMMExample {
volatile boolean signal = false;
public void doSignal() {
signal = true;
}
public void doWait() {
while(!signal) {
// 自旋等待
}
doSomething();
}
public void doSomething() {
// ...
}
}
该示例通过使用volatile关键字保证doSignal方法对signal的修改对doWait方法可见,避免了并发问题的发生。
所以,理解Java内存模型可以帮助我们编写正确的多线程程序,掌握避免并发问题的方法与手段。