版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuzhixiong_521/article/details/85246543
概述
如果你对volatile不陌生的话,应该会知道volatile能够保证共享变量对线程的可见性。
那为什么volatile无法保证 i++ 操作的线程可见性呢?
分析
假设i的初始值为0,现有两个线程,分别为线程1和线程2进行 i++ 操作,我们来分析一下为什么会出现错误。
首先,i++并不是原子操作,我们可以将这个操作拆分为3个步骤。
- 线程从主内存把遍历加载到缓存。
- 线程执行i++操作。
- 线程将i的新值刷新到主内存。
那么进行如下过程,则会发生线程安全问题。
- 线程1将变量加载到缓存。但是还没有执行 i++ 操作。
- 线程2将变量加载到缓存,然后执行i++操作。
- 由于线程2缓存变量已经发生了变化,使得线程1的缓存行无效。
- 按我们以前的理解,由于线程1缓存行无效,那线程1应该主动去主内存load最新的值。而实际上并不是这样的,volatile的作用并不是在变量改变的时候,让其他线程重新加载主内存的变量值,而是置其他线程缓存内的变量值无效。也就是说,此时线程1并不会重新去从主内存加载i的值,而是继续进行i++操作,导致数据错误。