线程间数据传递常用关键字——volatile

1、概述

在Java中,volatile是一个关键字,它用于确保多线程环境下的变量可见性;当一个变量被声明为volatile时,它可以确保所有线程都能正确地读取该变量的最新值。
注: a、可以确保变量的可见性,但它不能保证变量的原子性;
b、使用volatile时会禁止指令重排

2、volatile关键字的特性

a、可见性(保证)

在多线程环境中,每个线程都有自己的工作内存,每个线程对变量的修改都只存在于其自己的工作内存中,而不是直接修改在主内存(主存)中的变量。这可能会导致一个线程对变量的修改在其他线程中不可见,也就是出现了所谓的缓存不一致问题,通过volatile可以解决这个问题;

volatile 如何实现变量可见性?

volatile关键字的作用是禁止CPU缓存和编译器优化,从而确保每次读取变量时都会直接从主内存中获取最新值,而不是从工作内存中读取。这样,当一个线程修改了变量的值后,其他线程能够立即看到最新的值,从而实现了变量的可见性;

public class VolatileTest1 {
    private volatile static Boolean flag = true;

    public static void main(String[] args) {
        new Thread(() -> {
            while (flag) {
            }
            System.out.println("线程一运行");
        }).start();
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("线程二运行");
                flag = false;
                Thread.sleep(1000);
                System.out.println("线程二运行1");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

    }
}

b、原子性(不保证)

概述:原子性指的是某个线程正在执行某个操作时,中间不可以被加塞或分割,要么整体成功,要么整体失败。

public class VolatileAtomicityTest {
    public static volatile int i = 0;

    public static void main(String[] args) {
        int threadPoolSize = 20;
        ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
        for (int j = 0; j < threadPoolSize; j++) {
            executorService.submit(()->{
                System.out.println(Thread.currentThread().getName()+"----->"+i);
                i++;
            });
        }
        executorService.shutdown();
    }
}

在这里插入图片描述
根据上面的代码执行结果判断,volatile不能保证操作的原子性;一个线程在修改i的时候结果还没有告诉主内存,另一个线程又从主内存获取了i;索引执行i++操作是数据的原子性没有保证;可以通过加锁(synchronized,lock)或者原子类(Atomic)来确保数据安全

c、禁止指令重排

在多线程环境下,为了提高程序的执行效率,编译器和处理器可能会对指令进行重排。然而,这种重排可能会导致多个线程之间的操作出现竞态条件,从而产生不可预测的结果。

使用volatile关键字可以禁止指令重排。当一个变量被声明为volatile时,它会告诉编译器和处理器,这个变量可能会被多个线程同时访问,因此不能对其进行重排。这可以确保在多线程环境下,操作的顺序不会发生改变,从而避免竞态条件。

参考文献:
https://www.cnblogs.com/zhongqifeng/p/14684028.html
java汇编工具使用:
https://blog.csdn.net/z435128234/article/details/128099880

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值