提到java多线程,就不得不提volatile这个关键字,并且,这也是在面试中常常被问到的一个知识点。
一、基本概念
1.可见性
可见性是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是说,一个线程修改的结果,另一个线程能立即看到。
volatile修饰的变量就具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。注意:volatile只能保证被修饰内容具有可见性,但不能保证具有原子性。
比如volatile int a = 10;之后有一个a++;这个变量具有可见性,但a++依然不是一个原子操作,也就是这个操作同样存在线程安全问题。
在java中,synchronized,volatile,final可以实现可见性。
2.原子性
原子性是世界上最小的单位,具有不可分割性。比如a = 10,这具有原子性,不可分割;a++,这不具有原子性,可以分割。
非原子操作都具有线程安全问题,需要使用synchronized来变成一个原子操作。java.concurrent包下提供了一些原子类,比如AtomicInteger,AtomicLong,AtomicReference等。
3.有序性
java提供了volatile和synchronized两个关键字来保证线程之间操作的有序性。volatile其本身包含“禁止指令重排序”的语义,synchronized是“一个变量在同一时刻只允许一条线程对其进行lock操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行执行。
4.什么是volatile
a).运行线程访问共享变量,确保我们共享变量被所有线程拿到的值都是一致的。
b).为什么使用volatile?
- 保证我们数据的一致性
- 要有更好的性能,比同步关键字性能更好
5.共享变量
能被多个线程访问,那么就是共享变量
6.原子性
- 从主内存读取变量到cpu的寄存器
- 寄存器值+1
- 寄存器的值刷到主内存