类的生命周期:加载-->验证-->准备-->解析-->初始化-->使用-->卸载。
只有上述几种方法会主动加载类,其他引用类的方式不会都不会加载类。例如:
此外,加载接口时,不会加载父接口。
<clinit>()
方法。编译器收集的顺序是由语句在源文件中出现的顺序决定的。静态初始化代码块只能访问定义在该代码块之前的静态变量,定义在它之后的变量,代码块中只能对其赋值,但不能访问。<clinit>()
方法与类的构造函数不同,它不需要显示地调用父类构造器,由于加载本类时,会先加载父类,所以在初始化本类时,父类已经完成初始化。<clinit>()
方法对于类或接口来说不是必须的,当类或接口中没有静态初始化语句或静态初始化代码块时,就不需要 <clinit>()
方法。类加载器负责将.class文件加载到内存中,并为之生成对应的java.lang.class对象。
在Java中,一个类用其全限定类名(包括包名和类名)作为标识;但在JVM中,一个类用其全限定类名和其类加载器作为其唯一标识。即:两个类相等,必须满足两个类是由同一个类加载器加载,同时这两个类是相同包下的同一个class文件。否则,即使加载自相同的字节码文件,但类加载器不同,也会生成两个 class 对象。
常用的类加载器:
JAVA_HOME/lib
目录下的类。JAVA_HOME/lib/ext
目录下的类。classPath
上指定的类库。主要是当前工程目录下的类。双亲委派模型要求除了顶层的启动类加载器之外,其余的类加载器都要有自己的父类加载器。此处类加载器直接的父子关系一般不会以继承的关系实现,而是都使用组合关系来实现。
双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都会传送到顶层的启动类加载器中,只有当父类加载器没有找到所需的类时,子加载器才会尝试加载。
乐观锁:基于CAS实现。
synchronized 和 Lock的区别:一个是底层,一个是包实现,一个可中断,有公平性,有多个条件对象。乐观锁。
并发的三大特性:
锁优化的方法:
原文:https://www.cnblogs.com/echie/p/9867883.html