volatile 是什么?可以保证有序性吗?
1 个回答
世间万物,唯有过往伤人最深。冰心月### `volatile` 是什么?可以保证有序性吗? 一旦一个共享变量(类的成员变量、类的静态成员变量)被 `volatile` 修饰之后,那么它具备了两层语义: 1. **保证可见性**: - 不同线程对这个变量进行操作时的可见性。即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。 - `volatile` 关键字会强制将修改的值立即写入主存。 2. **禁止指令重排序**: - 禁止进行指令重排序,以保证程序在多线程环境下的执行顺序。 ### `volatile` 不是原子性操作 虽然 `volatile` 关键字保证了变量的可见性和部分有序性,但它并不保证操作的原子性。也就是说,对 `volatile` 变量的复合操作(如自增、自减)并不是线程安全的。 ### 保证部分有序性 当程序执行到 `volatile` 变量的读操作或者写操作时: - 在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见; - 在其后面的操作肯定还没有进行。 ### 我来对比说明 ### 使用 `volatile` 的情况 ```java int a = 0; volatile boolean flag = false; // 线程 1 a = 1; // 语句 1 flag = true; // 语句 2 // 线程 2 if (flag) { // 语句 3 // 这里 a 是 1 (语句 4) } ``` ### 不使用 `volatile` 的情况 ```java int a = 0; boolean flag = false; // 线程 1 a = 1; // 语句 1 flag = true; // 语句 2 // 线程 2 if (flag) { // 语句 3 // 这里 a 可能是 0,也可能是 1 (语句 4) } ``` ### 使用 `volatile` 的情况详解 当 `flag` 被声明为 `volatile` 时,Java 内存模型(JMM)确保了两个重要的规则: 1. **可见性**:当一个线程写入 `volatile` 变量,其他线程能立刻看到这个更新。 2. **有序性**:在写入 `volatile` 变量之前的所有操作(包括对非 `volatile` 变量的写操作)在写入 `volatile` 变量后都对其他线程可见。 具体来说: - **线程 1** 中 `a = 1` (语句 1) 发生在 `flag = true` (语句 2) 之前。 - `flag` 是 `volatile` 变量,写入 `flag` 之前的所有操作(包括 `a = 1`)在写入 `flag` 后对其他线程可见。 - **线程 2** 中,当 `if (flag)` (语句 3) 判断为 `true` 时,根据 `volatile` 的可见性保证,此时 `a = 1` 的修改已经对该线程可见。 因此,在使用 `volatile` 时,当 `flag` 为 `true` 时,`a` 一定是 `1`。 ### 不使用 `volatile` 的情况详解 当 `flag` 不是 `volatile` 时,Java 内存模型不保证 `flag` 的写入对其他线程立即可见,也不保证写入 `flag` 之前的操作对其他线程可见。 具体来说: - **线程 1** 中 `a = 1` (语句 1) 发生在 `flag = true` (语句 2) 之前。 - 因为 `flag` 不是 `volatile` 变量,所以其他线程不保证能立刻看到 `flag = true` 的修改。 - **线程 2** 中,当 `if (flag)` (语句 3) 判断为 `true` 时,可能是由于指令重排序、CPU 缓存等原因,`a = 1` 的修改还没有对该线程可见。 因此,在不使用 `volatile` 时,当 `flag` 为 `true` 时,`a` 可能是 `0`,也可能是 `1`。 ### 对比总结 - **使用 `volatile`**:`volatile` 保证了变量的可见性和部分有序性。当一个线程修改了 `volatile` 变量,其他线程能立即看到修改,并且写入 `volatile` 变量之前的操作对其他线程也可见。在这种情况下,当 `flag` 为 `true` 时,`a` 必然是 `1`。 - **不使用 `volatile`**:没有 `volatile` 的保证,变量的修改对其他线程可能不可见,且操作顺序可能被重排序。在这种情况下,当 `flag` 为 `true` 时,`a` 可能是 `0`,也可能是 `1`。 希望以上说明清晰地展示了 `volatile` 的作用及其对程序执行顺序和变量可见性的影响。发布于 2024-07-23 00:01 •IP属地 四川举报评论收藏
公众号进入网站体验更佳

