JVM那些事--类的初始化

类的初始化

一个正常的类初始化过程

如果父类还没有完成初始化,则先完成父类的初始化;

  1. Class对象处于被链接过,还未初始化的状态;
  2. 获取锁LC->记录Class对象的状态为初始化过程中->释放锁LC
  3. Class对象的状态为初始化过程中
  4. class文件中的ConstantValue属性中记录的常数值依次赋值给每个finalstatic字段;
  5. 执行类C<clinit>方法;
  6. 如果类C<clinit>方法正常完成,则获取锁LC->记录Class对象的状态为已完成初始化->通知所有等待线程->释放锁LC
  7. Class对象的状态为已完成初始化
  8. 如果类C<clinit>方法执行报错,则则获取锁LC->记录Class对象的状态为初始化报错->通知所有等待线程->释放锁LC
  9. Class对象的状态为初始化报错

如何在并发多线程环境里保证上述初始化过程的线程安全?

假设有两个线程A和线程B,线程A和线程B都执行到步骤2,开始竞争锁LC

方法一:

假设线程A在竞争中获得了锁LC,则记录Class对象的状态为被线程A控制的初始化过程中,然后释放了锁。然后,不管在后面的哪一步被抢占,都执行如下操作:如果线程B获得了锁LC,发现Class对象的状态为被线程A控制的初始化过程中,则线程B就释放锁LC,开始等待一直到收到线程A完成Class对象初始化的通知,正常完成。

哪些情形会触发类的初始化?

  • 虚拟机启动时触发initial类的初始化
  • 子类的初始化触发父类的初始化
  • 调用类库中的反射方法
  • 首次调用java.lang.invoke.MethodHandle实例
  • 虚拟机执行newgetstaticputstaticinvokestatic中任意一个指令
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,737评论 3 83
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,991评论 19 139
  • 转自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帅199207阅读 8,618评论 3 93
  • 我曾经写过一篇文章叫《上帝是如何把宙斯挤下神坛的》,那么上帝在成为唯一的神以后是怎么处理来自凡人的祈祷和愿望呢?忙...
    和坚阅读 934评论 11 7
  • 预习: if-else、if-elif-else、 知识点: 5.3 if语句 if语句有很多种,使用哪种取决于要...
    Mr_wang001阅读 202评论 1 0