面试官喜欢问的:Volatile关键字

273 阅读3分钟

在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度,而以volatile关键字作为一个小的切入点,往往可以一问到底,把Java内存模型(JMM),Java并发编程的一些特性都牵扯出来,深入地话还可以考察JVM底层实现以及操作系统的相关知识。 下面我们以一次假想的面试过程,来深入了解下volitile关键字吧!

JVM如何读写Volatile修饰的变量的

并发编程三大特性:可见性、有序性、原子性(原子)

Volatile关键字:线程之间让值可见,两个线程之间的数据可以通信了呢?

image.png

结论:解决并发编程的可见性

Java内存模型-JMM

主内存:栈内存、堆内存 每个线程在执行中有自己的内存

主内存 缓冲区 一直度缓存区的内存

cpu也有空闲的时间,去主内存刷新一下。一个线程修改了变量,另一个线程能感知到

主内存:方法区 + 堆区 工作内存:JVM内存模型中的虚拟机栈

image.png

指令重排(优点和缺点):性能高 内存屏障: happends-before: as-if-serial语义:

有序性:

指令重排:是一种现象,因为CPU是乱序执行的,早期CPU是顺序执行的

  • java层面 java层面有没有指令重排(java字节码) 没有重排

chang编译后生成的字节码文件是否一样,加或不加Volatile的情况下

idea插件:jclasslab

image.png

image.png

JVM如何知道的 属性访问的标志:Access Flag

计算深度:

  • java代码层面
  • java字节码
  • Hotspot源码 内存屏障 lock..
  • 重排
  • 汇编
  • CPU

image.png

DCL+ volatile

CPU是乱序执行的,但是有的代码不能乱序执行,乱序执行的话,结果就不对了。乱序执行的一种约束

image.png

内存屏障、编译屏障:

老师备课一周,我们学习只用几个小时

  • Hotspot层面

Volatile和synchronized对比

  • 比synchronized效率高
  • synchronized jdk1.8优化,效率也相对高一些
  • 并不能保证多个线程共同修改running变量时所带来的不一致问题,volatile不能替代syn
  • Volatile只保证可见性,不保证原子性;Syn都保证,效率低。

10个线程共同访问同一个变量,count=0

值比10000小

线程1:+100 线程2:100+1 不保证写的时候是否102

  • 解决同样的问题的更高效的方法:AtomXXX类,本事方法是原子性的,但不能保证多个方法连续调用都是原子的

count++ 不具备原子性的

锁:new真正的对象,锁的内存定义在堆内存中

  • 锁定某对象o,如果o的属性发生改变,不影响锁的使用,但是如果o变成另外一个对象,则锁定的对象发生改变,应该避免将锁定对象的引用变成另外的对象

  • 不要以字符串常量作为锁定的对象

wait和notify区别,原理

ReetTrantLock

在java多线程中,可以使用synchronized关键字实现线程之间同步互斥,但在JDK1.5中新增加了ReentranLock类也能达到同样的效果,并且在扩展功能上也更加强大,比如具有嗅探锁定、多路分支通知等功能,而且在使用上也比synchronized更加的灵活。

必须要手动释放锁

参考:juejin.im/post/684490…