从今天起每天发一篇java知识,由于本人是有基础的,所以内容可能不连贯,
如果想系统的学习java、请到这篇帖子
(重磅炸弹,原京东架构师编写)全套java学习笔记
https://www.52pojie.cn/thread-1260819-1-1.html
(出处: 吾爱破解论坛)
volatile :可见的,经常用来修饰共享变量,多线程中应用较多,意思是当共享变量内容被修改时,通知其他线程,这样其他线程就能知道他的值已经变化了。从浅到深,我们先来试试加了volatile和不加volatile的区别加了volatile--[Java] 纯文本查看 复制代码
public static int i=0;
public static void main(String[] args) {
Thread thread = new Thread(() -> {
sys();
});
Thread thread1 = new Thread(() -> {
sys();
});
Thread thread2 = new Thread(() -> {
sys();
});
thread.start();
thread1.start();
thread2.start();
}
public static void sys(){
while(i<100){
try {
Thread.sleep(100);//模拟下卡顿
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
System.out.println(Thread.currentThread().getName()+"-----"+i);
}
}
加了volatile之后,我们发现还是有重复值,然后又学到一个新的知识点1.i++不是一个原子操作,在多线程中不能保证一定执行-------具体:https://blog.csdn.net/huaweitman/article/details/383523452.volatile不能保证原子性,他提供了良好的可见性,就想i++如果没执行成功,值就没有变,其他线程也就还是用的原来的值,然后就出现一个值输出了两次,甚至更多.-----具体:https://blog.csdn.net/xdzhouxin/article/details/81236356
然后我们再深入了解一波,讲讲原理我们先回顾下基础知识。在多核CPU下,为了提高效率,线程都是直接到CPU缓存中拿值的,而不是内存。拿值时先到CPU缓存中找,没有再到内存中找,找到后拿到CPU缓存,再从缓存中拿出来,所以线程读操作始终在CPU缓存,这时就有个问题,CPU缓存中的值不一定和内存中的一样,所以在这里有个机制,内存会主动通知CPU缓存,告诉他当前共享变量的值已经失效了,从新再来拿一份。volatile关键字就是会触发这种机制,加了 volatile 关键字的变量,就会被识别成共享变量,内存中值被修改后,会通知到各个 CPU 缓存,使 CPU 缓存中的值也对应被修改,从而保证线程从CPU 缓存中拿取出来的值是最新的。
以上就是所有内容,明天再见 |