接上篇,上一篇我们讲到了线程的部分基础知识,传送门。本人本着相互学习的精神,如果有哪些知识理解不到位,或者错误的地方还请各位大神帮忙指正。好了言归正传,我们继续伐木。
接下来说一说并发编程的三大特性
①可见性
②有序性
③原子性
说到这里我们不得不说一下volatile这个关键字。
首先volatile的特性有两点
1.保证多线程之间的可见性。
例如Thread1和Thread2都到内存中读取r这个布尔值,放到线程的本地内存中,假如线程1对r重新赋值r=false写回主存中,在未对r这个值前面添加volatile关键字的时候,线程2是无法感知主存中r值的变化,线程2引用到r后依然还是从线程本地缓存的拿取r=true,若在编译初始化的前定义 volatile r =true,那么线程1对r值重新赋值,线程2也会感知的到。
2.防止指令重排序。防止乱序
为什么会存在乱序呢?其实单纯是为了提高效率。
举个栗子说明一下:
例如底层cpu寄存器中有两条指令,指令1是到内存中读取某一个值x,指令2是将另一个y值做++操作,我们知道寄存器操作指令所消耗的时间远远比到内存中读值要快的多的多,如果一定要按照指令执行顺序执行,也就是只等指令1到内存中读取完某个数之后再去执行指令2,指令1到内存中读取数的这段时间就什么也不干,效率就非常慢,所以cpu为了提高效率可能会将指令2放到指令1之前执行。也就是指令2优先执行,所以会出现乱序的情况出现。
那么什么情况下可能会出现乱序的情况呢?
其实很简单,前后两条指令没有依赖关系,也就是说指令1到内存中读出x的值,指令2对该x做++操作,这种情况就不可能发生乱序的情况。因为指令1和指令2有依赖关系,如上述栗子两条指令没有相互依赖的关系,那么就有可能会发生乱序执行的情况,如果在初始化时添加上volatile关键字就可以防止相邻指令的重排序,按照程序顺序执行了。