volatile关键字
多线程开发中主要关注因素
- 原子性
java中对基本数据类型的读取和赋值操作都是保证原子性的
I = 10; => cache 10; memory 10 原子操作
b=a; 1.read a 2. assign b = > 非原子操作 - 可见性
使用volatile保证可见性和有序性, 但不保证原子性 - 有序性
- Happens-befor原则就是保证有序性的
+ 在同一个线程中, 编写在前面的就在前面
+ 一个unLock操作先行发生于后面对同一个锁的lock操作;
+ volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
+ 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;
+ 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
+ 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
+ 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;
+ 传递性:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
- Happens-befor原则就是保证有序性的
volatile主要解决问题
- 有序性, 防止指令重排序
- 可见性, 多个线程对变量的操作都会立即写回主内存
volatile出现思考
volatile出现的原因主要是因为cpu的问题, 首先加入有两个线程一个线程去改一个变量一个线程去判断这个变量是否被改了然后进行输出,实际上不加volatile关键字是不能够实现的(因为只读操作不会吧二级缓存里面的数据刷写会主内存,也不会重新到主内存再次加载);
因为cpu和内存之间还存在一个二级缓存,每个线程在一个cpu执行时都有一块儿二级缓存那这样两个线程实际上看到的变量不是同一个