一,操作系统原理
ALU是运算单元,PC是程序计数器,Registers寄存器存储运算的数据。L1级缓存,L2级缓存方便对数据进行访问。
携程面试问到volatile可见性的实现,其实是用volatile声明的变量如果被某一个线程修改,首先该值会更新到主存去,通过对读,写设置内存屏障,注意两点1、一旦完成写入,任何访问这个字段的线程将会得到最新的值。2、在写入前,保证所有之前发生的事已经发生,并且任何更新过的数据值也是可见的,因为内存屏障会把之前的写入值都刷新到缓存。这里JVM要求的实现比较严格,存储和存储,读取和读取之间都有内存屏障(实现内存屏障的方式可能是lock锁总线,可能是原语)
二,多线程高并发
1,synchronized
必须是可重入锁:为什么?
当一个子类对象获取了锁,在执行过程中需要调用该子类父类的synchronized方法,由于都要获取一个对象的锁,如果不能重入,就会导致死锁。
synchronized锁的是对象
synchronized锁定的方法和非锁定的方法相互执行不冲突
synchronized不要用String,Integer,Long这些类型
synchronized底层实现(Hotspot的实现)
- jdk早期的重量级锁 - 找os申请锁。
- 后期改进引入锁升级策略 - sync(obj),第一个线程来获取时,再Markword上记录线程ID(偏向锁,可重入的基础),若有线程争用,则升级为自旋锁,(循环尝试获取锁,尝试10次),10次之后升级为OS层面的锁
2,volatile
保证线程可见性:
MESI 缓存一致性协议保证不同CPU之间的缓存可见性
禁止指令重排序
双重校验锁中new的问题