Volatile关键字理解

Volatile定义

为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。

特点

volatile修饰的共享变量,能保证可见性,不能保证原子性

什么是可见性?

一个线程对共享变量值得修改,能够及时的被其他线程读取到。
比如共享变量count=0;线程A修改为1,那么线程B拿到的count值应该是A修改过后的1,而不是0。

什么是原子性?

原子是世界上的最小单位,具有不可分割性。
原子性就是某种操作,要么全部执行,要么都不执行。
比如:银行转账的原子性,从A账户减1000元,给B账户加1000元,这2个操作要么全部执行,要么都不执行。

volatile实例

package com.thread;


/**
 * VolatileDemo类描述: 保证共享变量的“可见性”
 *      但是,不保证“原子性”
 *
 * @author yangzhenlong
 * @since 2018/1/21
 */
public class VolatileDemo extends Thread{
    private boolean  flag = true;

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public void run(){
        System.out.println("自定义线程...start...");
        while (flag){//当flag=true,线程不结束

        }
        System.out.println("自定义线程...end...");
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileDemo t = new VolatileDemo();
        t.start();
        Thread.sleep(3000);
        t.setFlag(false);
        System.out.println("-----------main线程-----------end");
    }
}

执行main方法后,发现3秒后,设置flag=false,自定义线程并没有停止

 

原因

如下图,每个为了更高效的执行计算,都有自己的本地内存(cpu高速缓存,也叫工作内存),程序启动时,每个线程都会从主存中拷贝共享变量flag到自己的本地内存中。而计算的操作也是在本地内存中取值的。当主线程修改了值并通知刷新主存后,自定义线程仍然读的是自己的本地内存的值为true,所以仍然执行,并未停止。

 

 而volatile修饰后,主存发现共享变量的值发生改变后会及时通知自定义线程,自定义线程拿到的值flag=false,此时停止执行。

 

修改代码:

private volatile boolean  flag = true;

再次执行,3秒后,线程停止

 

转载于:https://www.cnblogs.com/yangzhenlong/p/8325888.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值