Java软件工程师 2018-10-15 15:24 采纳率: 50%
浏览 863
已采纳

是什么导致一个类被clinit了多次?

这是我的Springboot启动的的图
图片说明
如图所示:
com.essence.framework.support.jdbc.JdbcUtil这个类之前被初始化过一次,里面的静态属性已经被赋值了,但是后来调用的时候发现,静态属性值莫名变成null了。
于是我把调用堆栈信息打印了出来。
发现该类被clinit了两次!第一次是我人为控制初始化的,自然属性值什么的都赋值了。
但是为什么第二次使用的时候,又被clinit了呢?

  • 写回答

3条回答 默认 最新

  • Java软件工程师 2018-10-16 05:34
    关注

    关于clinit是这么解释的:
     --引文--
    虚拟机会保证一个类的clinit()方法在多线程环境中被正确的加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的clinit()方法,其他线程都需要阻塞等待,直到活动线程执行clinit()方法完毕。需要注意的是,其他线程虽然会被阻塞,但如果执行clinit()方法的那条线程退出clinit()方法后,其他线程唤醒后不会再次进入clinit()方法。同一个类加载器下,一个类型只会初始化一次。

    为什么我的JdbcUtil被clinit了两次。

    ----已解决,完结撒花---
    错误原因,我引入了devtools依赖。
    错误分析:我在jdbcUtil中添加static代码块,在其中输出了classloader。发现:第一次加载时候的classloader为:org.springframework.boot.devtools.restart.classloader.RestartClassLoader,第二次加载的时候的classloader为:sun.misc.Launcher$AppClassLoader。我的JdbcUtil第一次初始化静态全局变量是在ServletContextListener监听中,该监听中的所有类都是由devtools的RestartClassLoader加载的。后面使用jdbcUtil的时候,却是用AppClassLoader加载的,导致JdbcUtil被加载了两次,丢失了第一次加载时初始化的值。
    结论: 删掉devtools依赖搞定,如果需要在启动监听中初始化值,就最好不要引用devtools,它自己实现了一个classloader,会导致你初始化的对象/值,因为后来类被AppClassLoader重新加载而丢失

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)