浅谈volatile在i++情况下失效

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuzhixiong_521/article/details/85246543

概述

如果你对volatile不陌生的话,应该会知道volatile能够保证共享变量对线程的可见性。
那为什么volatile无法保证 i++ 操作的线程可见性呢?

分析

假设i的初始值为0,现有两个线程,分别为线程1和线程2进行 i++ 操作,我们来分析一下为什么会出现错误。

首先,i++并不是原子操作,我们可以将这个操作拆分为3个步骤。

  1. 线程从主内存把遍历加载到缓存。
  2. 线程执行i++操作。
  3. 线程将i的新值刷新到主内存。

那么进行如下过程,则会发生线程安全问题。

  1. 线程1将变量加载到缓存。但是还没有执行 i++ 操作。
  2. 线程2将变量加载到缓存,然后执行i++操作。
  3. 由于线程2缓存变量已经发生了变化,使得线程1的缓存行无效。
  4. 按我们以前的理解,由于线程1缓存行无效,那线程1应该主动去主内存load最新的值。而实际上并不是这样的,volatile的作用并不是在变量改变的时候,让其他线程重新加载主内存的变量值,而是置其他线程缓存内的变量值无效。也就是说,此时线程1并不会重新去从主内存加载i的值,而是继续进行i++操作,导致数据错误。

猜你喜欢

转载自blog.csdn.net/liuzhixiong_521/article/details/85246543
今日推荐