java中volatile为什么可见性_java volatile 实现变量可见性

java volatile 实现变量可见性

volatile 本意是易变的,多变的,用来解决变量可见性问题,什么是变量可见性问题?先看一下变量在计算机内部第一次加载和写入过程:

c96520dd98f591bc5fa5bf2f5ef2f2c7.png

此时,内存和寄存器中v都是101,再进行计算时时直接从register中读取而不是memroy来提高速度。这在单核CPU中没毛病,如果是多核CPU中,变量v在各自寄存器中都有值了,即使内存中的变量v更新了它还是从寄存器的缓存中读取,就会导致程序运行结果不符合预期,变量的可见性,指的是它被修改后其他线程可以立即看到最新结果的能力。使用一个用例来复现这种现象:

创建一个全局变量running

创建一个名为ObserveThread子线程,让它不停观察running的值(预期它在不停地从寄存器中读值)

在主线程中修改running的值,观察子线程/和主线程中的值是否发生变化(预期子线程的没变,主线程的变了)

代码:

package juc.test.sharememroy;

public class StaticVolatileTest {

static /*volatile*/ boolean running = true;

public static void main(String[] args) {

new Thread("ObserveThread"){

@Override

public void run() {

System.out.println("thread start");

while (running){}

System.out.println("thread end");

}

}.start();

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

running = false;

System.out.println("main thread end, running = " + running);

}

}

3秒后线程没有结束,查看JVM中的线程状态发现ObserveThread还在Running:

e31e11760d8c5aad829d6a20b3a839d6.png

控制台输出结果:

thread start

main thread end, running = false

可以说明ObserverThread 线程没读取到主线程修改后的值,而是从它的缓存中读值,只要将

static /*volatile*/ boolean running = true;

修改为:

static volatile boolean running = true;

问题就解决了,输出就变成:

thread start

main thread end, running = false

thread end

volatile是使用缓存一致性协议实现的,对于可能频繁修改的变量,每次不从寄存器而是从内存中读取,降低速度来保证可见性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值