一个类会被初始化几次?多线程情况下如何保证类的初始化?【初始化阶段】 www.bilibili.com/video/BV1SP…
示例:
- 当static块在前面,修改了在其之后定义的变量时:
- 当变量定义在static块之前,static块中修改变量的值:
注意2:父类初始化先执行
方法与类的构造函数(在虚拟机视角中的实例构造器init方法)不同,它不需要显示调用父类构造器,虚拟机会保证在子类的clinit方法执行前,父类的clinit方法已经执行完毕,因此在java虚拟机中第一个被执行的clinit方法的类型肯定是java.lang.Object。
示例:
注意3:线程同步
java虚拟机必须保证一个类的clinit方法在多线程环境中被正确的加锁同步,如果多个线程同时区初始化一个类,那么只会有其中一个线程去执行这个类的clinit方法,其他线程需要阻塞等待,直到活动线程执行完毕clinit方法。如果在一个类的clinit方法中有耗时很长的操作,那就可能造成多个进程阻塞,在实际应用中这种阻塞往往是很隐蔽的。
示例:
可以看到其他线程阻塞住
虽然其他线程会被阻塞,但如果执行clinit方法的那个线程退出clinit方法后,其他线程唤醒后则不会再次进入clinit方法。同一个类加载器下,一个类型只会被初始化一次。
示例:可以看到只执行了一次:init DeadLoopClass