【Java并发编程】深入理解并发可见性、有序性、原子性与JMM内存模型
发布人:shili8
发布时间:2025-03-01 13:34
阅读次数:0
**Java 并发编程**
在 Java 中,多线程程序的并发性是非常重要的。然而,在多线程环境中,共享变量之间的可见性、有序性和原子性可能会导致问题。在本文中,我们将深入探讨这些概念,并且使用 JMM(Java Memory Model)内存模型来解释它们。
###1. 并发可见性并发可见性是指在多线程环境中,一个线程对共享变量的修改是否能被其他线程立即看到。换句话说,是指当一个线程改变了某个共享变量的值时,这个变化是否能够立即传播到其他线程。
**示例代码**
javapublic class VisibilityExample { private static int sharedVar =0; public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() -> { sharedVar =10; }); Thread thread2 = new Thread(() -> { while (sharedVar ==0) {} System.out.println(sharedVar); }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); } }
在这个例子中,我们有一个共享变量 `sharedVar`,它的初始值是0。线程1 将其设置为10,而线程2 会一直循环检查直到 `sharedVar` 不再等于0。
**问题**
如果我们不考虑并发可见性,这个程序可能会出现问题,因为线程2 可能会在线程1 修改 `sharedVar` 之前就读取了它的值。因此,线程2 将看到一个错误的值,即0。
###2. 并发有序性并发有序性是指在多线程环境中,操作之间的执行顺序是否能保证一致性。在 Java 中,有序性是通过内存模型来实现的。
**示例代码**
javapublic class OrderingExample { private static int a =0; private static int b =0; public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() -> { a =10; b =20; }); Thread thread2 = new Thread(() -> { if (a ==10 && b ==20) { System.out.println("有序性成立"); } else { System.out.println("有序性不成立"); } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); } }
在这个例子中,我们有两个共享变量 `a` 和 `b`,它们的初始值都是0。线程1 将 `a` 设置为10,然后将 `b` 设置为20,而线程2 会检查 `a` 和 `b` 的值是否一致。
**问题**
如果我们不考虑并发有序性,这个程序可能会出现问题,因为线程2 可能会在线程1 将 `a` 和 `b` 都设置为10 之前就读取了它们的值。因此,线程2 将看到一个错误的结果,即 `a ==10 && b !=20`。
###3. 原子性原子性是指在多线程环境中,操作之间的执行顺序是否能保证一致性。在 Java 中,原子性是通过内存模型来实现的。
**示例代码**
javapublic class AtomicityExample { private static int sharedVar =0; public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(() -> { for (int i =0; i < 10000; i++) { sharedVar++; } }); Thread thread2 = new Thread(() -> { for (int i =0; i < 10000; i++) { sharedVar--; } }); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(sharedVar); } }
在这个例子中,我们有一个共享变量 `sharedVar`,它的初始值是0。线程1 将其设置为10000,而线程2 将其设置为 -10000。
**问题**
如果我们不考虑原子性,这个程序可能会出现问题,因为线程1 和线程2 可能会同时修改 `sharedVar`,导致它的值被破坏。
### 总结在 Java 中,多线程环境中的并发可见性、有序性和原子性是非常重要的。通过使用 JMM 内存模型,我们可以保证这些属性的一致性。在本文中,我们深入探讨了这些概念,并且提供了示例代码来演示它们的应用。
**参考**
* 《Java 并发编程实战》第2 章:并发可见性* 《Java 并发编程实战》第3 章:并发有序性* 《Java 并发编程实战》第4 章:原子性