java面试 (12)- Valiolate原理?是线程安全的吗?
1:导致线程问题的原因:
抢占式执行
多个线程同时修改了同一个变量
非原子性操作
内存可见性问题
指令重排问题
2:并发编程三大特性
可见性(读线程不能及时的读取到其他线程写入的最新值,主要是CPU存在高速缓存,所以会有数据不一致的问题)
原子性
有序性
3:volatile关键字
volatile解决了内存可见性和指令重排序的问题
写volatile变量:改变线程工作内存中的valatile变量的值,会立即从工作内存刷新到主内存中,
新值对所有线程立即更新。
读volatile变量:先从主内存读取volatile变量的最新值到线程的工作内存中,再从工作内存中读取volatile变量的副本值。
在多线程环境下volatile修饰的变量值一定是最新的。
volatile避免了指令重排优化(在单线程的情况下,指令重排优化没有问题,但是多线程的情况下有有问题),实现了有序性。
( 内存屏障(也叫内存栅栏):一组处理器指定,用于实现对内存操作的顺序限制)
内存屏障(Memory Barrier)是计算机系统中用于控制内存访问顺序的一种机制。在多线程编程中,由于线程之间的并发执行,对共享内存的访问可能会出现不确定的结果,例如数据竞争(Data Race)和内存可见性(Memory Visibility)问题。内存屏障的作用是通过限制和约束内存访问的顺序,来解决这些问题。
内存屏障可以分为两种类型:读屏障(Read Barrier)和写屏障(Write Barrier)。读屏障用于保证对共享数据的读取操作不会读取到旧的、过时的值,而写屏障用于确保对共享数据的写入操作对其他线程是可见的。
读屏障(也称为加载屏障或获取屏障)会阻止任何后续的读操作重排到该屏障之前,以确保读操作获得的值是最新的。这样可以避免读取到过时的数据,保证读取操作的正确性。
写屏障(也称为存储屏障或释放屏障)会阻止任何前面的写操作重排到该屏障之后,以确保写操作对其他线程是可见的。这样可以保证写入操作的结果对其他线程是可见的,并避免写入操作和后续的读操作重排。
内存屏障在多线程编程中扮演重要的角色,它们可以通过指令级别的屏障(如CPU指令)或高级的同步原语(如互斥锁、信号量等)来实现。程序员可以使用内存屏障来显式地控制内存操作的顺序,从而避免数据竞争和内存可见性问题,保证多线程程序的正确性和一致性。