12. Java并发编程 volatile

本文详细解释了Java中的volatile关键字如何防止指令重排序和保证可见性,以及在VolatileTest示例中的应用。然而,尽管volatile确保可见性,但它不能保证操作的原子性。
摘要由CSDN通过智能技术生成

volatile

Java并发编程 volatile

volatile是一个关键字,用于声明变量。它的主要作用是告诉编译器,这个变量可能会被多个线程同时访问,因此不应该进行某些优化,而应该确保对这个变量的读写操作在多线程环境下是正确的。volatile关键字的主要作用包括两点:

  1. 禁止指令重排序volatile关键字保证了变量的读写操作不会被重排序,这对于某些需要依赖于操作顺序的场景是非常重要的。
  2. 保证可见性:当一个线程修改了一个volatile变量的值时,这个新值会立即对其他线程可见,确保了多线程之间对变量的可见性。

原理:

Java虚拟机(JVM)中,每个线程都有自己的工作内存,工作内存中保存了变量的副本。当一个线程修改了变量的值时,首先会在自己的工作内存中进行修改,然后将修改后的值刷新到主内存中。而其他线程在读取这个变量的值时,会首先从主内存中读取最新的值到自己的工作内存中,然后再进行操作。

volatile关键字的作用就是当一个线程修改了volatile变量的值时,会立即将修改后的值刷新到主内存中,而当其他线程读取这个变量的值时,会直接从主内存中获取最新的值,而不是从自己的工作内存中获取。这就保证了对volatile变量的读写操作在多线程环境下是正确的。

小试牛刀

public class VolatileTest {
    //public volatile int inc = 0;
    public int inc = 0;

    public void increase() {
        inc++;
    }

    public static void main(String[] args) throws InterruptedException {
        final VolatileTest test = new VolatileTest();

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,
                10,
                1000,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 10; i++) {
            threadPoolExecutor.execute(() -> {
                for (int j = 0; j < 1000; j++) {
                    test.increase();
                }
            });
        }
        threadPoolExecutor.shutdown();
        System.out.println(test.inc); //每次结果都不一样
    }
}

结果小于10000
volatile关键字能保证可见性没有错,但是上面的程序错在没能保证原子性。可见性只能保证每次读取的是最新的值,但是volatile没办法保证对变量的操作的原子性。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值