final:意思是不可变的
1.修饰类时:表示这个类不可被继承
2.修饰方法时:表示这个方法不可被重写
3.修饰变量时:表示该变量在声明时就必须初始化,而且后面不能修改其内存地址,并没有说不能修改里面的值,比如List,Map中可以修改其中的值。
static:表示为静态 全局 与对象无关 在一定访问可以被共享
1.修改变量时,在类被加载的时候就会初始化,如果该变量时public修饰 表示该静态变量可以被任何类访问,不需要new 对象调用 ,可以直接通过类名.static变量调用即可。
在多线程情况下对共享变量进行读写会存在并发安全问题,比如在类中定义static List<String> list = new ArrayList<String>(); 在多个线程下操作list会出现安全问题。
2.修饰方法时,代表方法与类无关,如果是public修饰的话,可以直接通过类名调用,static方法中的局部变量不会存在线程安全问题,方法在运行时,数据是运行在栈中的,数据是线程独占的,线程之间是隔离的。
3.修饰代码块, 该代码块常用在类启动之前 ,帮我初始化一些值。
volatile:可见的,修饰某个共享变量,当共享变量值被修改了,会通知到其他线程,其他线程就知道共享变量的值被修改了。
原理:当一个线程修改了共享变量的值,修改的是内存中的值,但是线程在拿值时是和CPU缓存打交道, 线程修改的是内存中的值,此时内存中的值和CPU缓存的值不一致,volatile就会触发一种机制,内存会通知CPU缓存,共享变量值被修改了 ,CPU缓存的值已经失效了,CPU缓存从内存中重新拿取新的数据。此时每个CPU缓存都存的是共享变量的新值。其他线程从CPU缓存中读取到的值都是修改之后的值。
如图:
volatile原理