什么是Java内存模型(JMM)?如何避免并发问题?代码举例讲解

Java内存模型(JMM)是一种抽象结构,描述Java程序中各线程与内存的交互方式。它规定了线程如何观察和操作共享变量,用于避免各种并发问题的发生。

JMM主要围绕三个方面进行规定:

  1. 原子性:要求对原子操作的执行结果,要么所有的线程都可见,要么所有的线程都不可见。
  2. 可见性:要求一个线程对共享变量的修改,要及时的变为其他线程可见。
  3. 有序性:要求程序执行的顺序按照代码的顺序执行。

要避免并发问题,我们需要:

  1. 使用volatile关键字:可见性,禁止指令重排序。
  2. 使用synchronized关键字:原子性,可见性,有序性。
  3. 使用Atomic包下的类: CAS机制实现原子性。
  4. 不可变对象:共享对象的状态不能被修改。
  5. 避免过长的字符串串联:会产生临时对象,破坏有序性。
  6. 用局部变量取代非常量的静态变量:避免可见性问题。

来看一个简单例子:

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内存模型可以帮助我们编写正确的多线程程序,掌握避免并发问题的方法与手段。