多线程学习:volatile关键字的作用

volatile关键字在于保证了线程可见性,线程的可见性涉及到Java虚拟机内存模型,用以下例子进行说明:
public class Volatile {

    /*volatile*/ static boolean running = true;

    public static void threadMethod() {
        //4.主线程执行完毕后线程开始执行打印 start thread
        System.out.println("start thread");
        //5.这时正常情况下running应该为false 并且不进入死循环
        while (running) {

        }
        //6.并且最后打印end thread
        System.out.println("end thread");
    }
    //当启动main方法后
    public static void main(String[] args) {
        //1.首先会创建线程并调用threadMethod方法
        new Thread(Volatile::threadMethod).start();
        //2.然后睡眠1秒
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //3.将running 设置为false
        running = false;
    }
}

正常情况下应该如上方的注释的顺序进行执行,但是运行结果却如下所示:

start thread

并没有打印end thread,这就涉及到了JMM(Java虚拟机内存模型),在Java虚拟机中运行线程时,涉及到主内存和CPU运行缓冲区,以以上例子做说明,当我们启动线程后读取到的running 的值首先是ture,此时CPU会将该值加载到CPU的线程缓冲区当中,而当运行running = false 后主内存中的值已经发生改变,但是由于running 的值原本是ture从而导致while 循环一直是死循环,但是由于CPU一直忙于while 循环,一直没有空闲时间从主内存中重新进行获取数据导致了CPU缓冲区中的数据一直是ture,从而导致了线程一直无法执行完毕,而volatile关键字在于保证了线程的可见性,当running 发生改变时,将会通知线程数据发生了改变,而线程将从主内存中重新加载数据,并执行,当去掉volatile关键字的注释后运行正常如下所示:

start thread
end thread

volatile关键字保证了线程可见性但是不保证线程原子性,而synchronized关键字既保证了线程的可见性又保证了线程的原子性,但是synchronized关键字的性能比volatile关键字的性能地的多

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值