多线程面试题
- synchronized与lock的区别
2.volatile的可见性和禁止指令重排性是怎样实现的
DCL在面试中可能被问到的问题:
volatile是否需要加? 答:需要加,在计算机指令中,, CPU和编译器为了提升程序的执行效率, 通常会按照一定的规则对指令进行优化, 如果两条指令互不依赖, 有可能它们执行的顺序并不是源代码编写的顺序,这可以称之为指令重排序,比如正常情况下 instance = new Instance()可以分成三步: 分配对象内存空间(此时值为默认值) 初始化对象成员变量 设置instance(栈内存中)指向刚刚分配的内存地址, 此时instance != null (重点) 因为2和3两步不存在数据上的依赖关系, 即在单线程的情况下, 无论2和3谁先执行, 都不影响最终的结果, 所以在程序编译时, 有可能它的顺序就变成了 分配对象内存空间(此时值为默认值) 设置instance(栈内存中)指向刚刚分配的内存地址, 此时instance != null (重点) 初始化对象成员变量 假设此时第一个线程正好被指令重排序,且执行到了第二步——设置instance(栈内存中)指向刚刚分配的内存地址,此时的instance != null,那么第二个线程取的时候,他所拿到的,就是刚刚分配了默认值的对象,而不是我最终想要的结果。 那么加了volatile之后会有什么不同呢? volatile有三个特点: 保证可见性 不保证原子性 禁止指令重排