final

  1. final 修饰类,表示类无法被继承,例如 String。
  2. final 修饰方法,表示方法无法被重写,但可以重载该方法,另外 final 修饰的方法,在字节码中可能不通过 invoke 的指令进行调用,而是将方法直接内嵌到字节码中进行执行,从而提高效率。
  3. final 修饰成员变量,表示变量一旦赋值不可再改变,也就是常量,对于引用变量来说,final 只是保证引用的对象地址不会发生改变,但对象的属性依然可以改变,final 修饰的成员变量必须在声明时或是构造方法中进行赋值,即必须在类的初始化阶段赋值。
  4. final 修饰方法参数,表示在方法执行过程中,参数不能发生改变,比如匿名内部类和局部内部类,需要使用方法参数时,只能使用 final 修饰的局部变量。

static

  1. static 修饰类,表示静态类,静态类只有静态的成员,并且不可以被实例化,但可以有静态构造方法。
  2. static 修饰方法,表示类的方法而不是具体实例的方法,静态方法会在类的加载阶段分配内存空间并加载,在字节码中使用 invokestatic 指令执行,在调用时不要需要类的实例对象,静态方法中只能访问静态成员。
  3. static 修饰成员变量,表示类的变量而不是具体实例的变量,静态的成员变量会在类加载的链接的准备阶段分配内存空间,且生命周期与程序的运行周期一致。
  4. 静态代码块与非静态代码块,都会在类加载的初始化阶段执行,执行的顺序都是按照代码中声明的先后顺序,区别是先执行静态代码块,并且如果存在多个线程,会由 JVM保证类的静态代码块只会执行一次,利用这个机制可以实现饿汉式的单例模式。

volatile

volatile 用于保证多线程操作同一个变量时的可见性与有序性,不能保证原子性

可见性

在线程启动时,会将需要的共享变量加载至本地缓存,线程对共享变量的读写会在本地缓存中执行,对其他线程是不可见的,使用 volatile 修饰的变量,对其的读操作会强制线程从主存中读取最新的数据,写操作会强制线程将写操作同步到主存。

有序性

JVM 在保证 as-if-serialhappens-before 规则的前提下,会对字节码指令进行重排,其中 happens-before定义了一些重排的特殊规则,例如 Sychronized 同步代码块前的指令不能排到代码块之后,而 as-if-serial 则是规定在单线程运行下,重排后的运行结果与重排前一致,但在多线程情况下,可能会存在问题,即有序性问题,volatile 关键字通过内存的读写屏障,即在 volatile 修饰的变量的写操作之前的所有指令,不能重排到写操作之后,读操作之后的指令,不能重排到读操作之前,其实 volatile 本身就是 happens-before 中的一条规则

native

本地方法,大多数和线程状态有关的方法,以及 Object 的 hashcodecloneintern 等方法。

关于Volatile后面会单拎出来详解。

本文文档

© 版权声明
评论 抢沙发

请登录后发表评论

    暂无评论内容