多线程的异步死循环和volatile关键字
Posted IT编程之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程的异步死循环和volatile关键字相关的知识,希望对你有一定的参考价值。
在研究volatile关键字的时候先写一个简单的程序实验,代码如下:
RunThread.java线程类
测试类TestTwo.java
运行结果:
运行结果是死循环,和我们想要实现的逻辑有冲突,为什么会出现这样死循环?
在启动RunThread.java线程时,变量runing=true;存在与公共堆栈及线程的私有堆栈中。线程一直在私有堆栈中取的runing的值时true。而代码thread。setRuning(false);虽然被执行,更新的却是公共堆栈中的runing变量值false,所以一直就是死循环的状态。内存结构图如下:
这个问题其实就是私有堆栈中的值和公共堆栈中的值不同步造成的。解决这样的问题就要使用volatile关键字了。她主要的作用就是当线程访问runing这个变量时,强制性从公共堆栈中进行取值。下面我们修改代码如下:
运行结果:
运行结果线程停止了,通过使用volatile关键字,强制的从公共内存中读取变量的值,内存结果读取变化如下图:
使用volatile关键字增加了实例变量在多个线程之间的可见性。但volatile关键字最致命的缺点是不支持原子性。
下面将关键字synchronized和volatile进行比较一下:
1)关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且volatile只能修饰与变量,而synchronized可以修饰方法,以及代码块。随着jdk版本的更新,synchronized关键字在执行效率上得到很大提升,在开发中使用synchronized关键字的比率还是比较大的。
2)多线程访问volatile不会发生阻塞,而synchronized会出现阻塞
3)volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接的保证可见性,可以它会将私有内存和公共内存中的数据做同步。此知识点在后面有实验做论证。
4)再次重申一下,关键字volatile解决的是变量在多个线程之间的可见性;而synchronized关键字解决的是多个线程之间访问资源的同步性。
线程安全包含原子性和可见性两个方面,Java的同步机制都是围绕这个两个方面来确保线程安全的。
大家在学习过程中遇到过什么问题也欢迎在留言区盖楼讨论!
以上是关于多线程的异步死循环和volatile关键字的主要内容,如果未能解决你的问题,请参考以下文章