«

Java中volatile关键字的作用与线程安全分析

磁力搜索 • 4 天前 • 1 次点击 • 资讯分享


volatile关键字在java中主要用于保证变量的可见性和禁止指令重排序,但不能保证原子性。1.可见性:当一个线程修改了volatile变量的值,其他线程可以立即得知该新值,因为每次读取和写入都直接与主内存交互;2.禁止指令重排序:通过插入内存屏障防止jvm优化时改变指令顺序,从而避免多线程环境下的意外行为;3.不保证原子性:对于如i++这样的复合操作,volatile无法确保线程安全,此时仍需使用锁机制;4.适用场景:适用于一个线程写、多个线程读的情况,例如状态标记或单例模式中的双重检查锁定;5.误用场景:不应用于涉及多个线程同时写入、复合操作或依赖当前值的操作;6.与synchronized的区别:volatile不提供原子性和锁机制,开销较小,适合简单状态同步,而synchronized能保障原子性、可见性和有序性,适合需要互斥访问的复杂并发控制。

Java中volatile关键字的作用与线程安全分析

volatile 关键字在 Java 中主要用于保证变量的可见性和禁止指令重排序,但它并不能保证原子性,因此不能完全解决线程安全问题。它适用于一个线程写,多个线程读的场景。

Java中volatile关键字的作用与线程安全分析

解决方案

volatile 关键字的作用在于:

Java中volatile关键字的作用与线程安全分析
  1. 可见性: 当一个线程修改了被 volatile 修饰的变量的值,这个新值对于其他线程来说是可以立即得知的。 这是通过在每次读取变量时都从主内存中读取,每次写入变量后都立即写回主内存来实现的。

    立即学习“Java免费学习笔记(深入)”;

    Java中volatile关键字的作用与线程安全分析
  2. 禁止指令重排序: volatile 可以防止 JVM 对其修饰的变量进行指令重排序优化,从而避免一些意想不到的并发问题。指令重排序是指 JVM 为了优化程序的执行效率,在不影响单线程程序语义的情况下,可以重新安排指令的执行顺序。但在多线程环境下,指令重排序可能会导致程序出现错误。volatile 通过插入内存屏障来禁止指令重排序。

然而,volatile 并不能保证原子性。原子性是指一个操作是不可中断的,要么全部执行成功,要么全部执行失败。对于复合操作(例如 i++),volatile 是无能为力的。

举个例子:

public class VolatileExample {
    private volatile int counter = 0;

    public void increment() {
        counter++; // 这是一个复合操作:读取-修改-写入
    }

    public int getCounter() {
        return counter;
    }
}
登录后复制


    还没收到回复