volatile关键字

valotile关键字

当一个变量定义为valotile之后,就保证了此变量对所有线程的可见性,可见性是指:当一个线程改变了这个变量之后,新值对于其他线程来说是可以被立即感知的。在读取一个volatile字段之前,各线程中缓冲区必须失效,因为值是存在于主存中而不是各线程中缓冲区。而普通变量不能做到这一点,普通变量的值在线程间传递需要通过主内存来完成。如:线程A修改了一个普通变量的值,然后向主内存进行回写,另外一个线程B在线程A回写完成之后再从主内存进行读取操作,新变量值才会对线程B可见

测试用例:

public class VolatileTest {


    private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger(1);
    private static volatile int index = 1;

    public static void main(String[] args) throws InterruptedException {

        final CountDownLatch startLatch = new CountDownLatch(1);
        Thread[] threads = new Thread[20];
        for (int i=0; i < 20; i++){
            threads[i] = new Thread(){

                @Override
                public void run() {
                    try {
                        startLatch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    for (int j = 0; j < 10000; j++){
                        index ++;
                        ATOMIC_INTEGER.incrementAndGet();
                    }
                }
            };
            threads[i].start();
        }
        Thread.sleep(200);
        startLatch.countDown();
        for (Thread t: threads){
            t.join();
        }
        System.out.println("AtomicInteger最终运行结果: "+ ATOMIC_INTEGER.get());
        System.out.println("volatile修饰参数运行结果: "+ index);

    }

}

结果:

// 可能结果1
AtomicInteger最终运行结果: 200001
volatile修饰参数运行结果: 195631

// 可能结果2
AtomicInteger最终运行结果: 200001
volatile修饰参数运行结果: 200001

使用valotile关键字,并不能保证在多线程环境下变量的线程安全问题,因为它只保证了可见性禁止指令重排(instruttive-reorder),并不保证原子性禁止指令重排保证了在线程内在指令执行的串行性

简而言之,volatile变量自身具有下列特性:

  • 可见性。对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
  • 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。
volatile写-读的内存语义
  • volatile写的内存语义: 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存
  • volatile读的内存语义:当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。

finalSynchronized关键字也是禁止指令重排的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值