线程可见性问题 volatile-final-static jvm(jit)缓存

# java 可见性问题 ## 什么是可见性问题 > 一个线程写值(先写),子线程读(后读)值,读不到,就是线程的可见性问题 >高速缓存和指令重排会导致可见性问题 ![image.png](https://cos.easydoc.net/31477061/files/km3blsdz.png) ## JVM的jit编译 和CPU 会导致 指令重排 ### 什么是jit ![image.png](https://cos.easydoc.net/31477061/files/km3bz2k6.png) > 程序运行的时候 对热点代码 进行编译升机(相当于把代码缓存起来) 不在去一次一次的读,就造成了,可见性问题。 ## java 是脚本语言?还是编译语言 ![image.png](https://cos.easydoc.net/31477061/files/km3cawdw) ## volatile解决线程可见性问题 ![image.png](https://cos.easydoc.net/31477061/files/km3cgl7y.png) ![image.png](https://cos.easydoc.net/31477061/files/km3cij1e.png) --- ![image.png](https://cos.easydoc.net/31477061/files/km4fgv25.png) ## final - Java中的String类就是一个final类 - 类的private方法会隐式地被指定为final方法。 - 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。 - 很多时候会容易把static和final关键字混淆,static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变 ![image.png](https://cos.easydoc.net/31477061/files/km4fzd1e.png) ![image.png](https://cos.easydoc.net/31477061/files/km4frks9.png) ## static - “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。” - 方便在没有创建对象的情况下来进行调用(方法/变量)。 - 静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。 - static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。 ![image.png](https://cos.easydoc.net/31477061/files/km4gjp31.png) - 因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。