[讨论] JVM虚拟机如何来初始化构造方法的
xgj1988
2011-04-08
面先说一下环境,比如现在有两个类,A和B,两个类都是单例类,这个时候如果A有个B的实例变量,B有个A的实例变量,会发生什么情况呢?开始我以为会出现栈溢出。但是让我迷惑的是,居然没问题。只是其中一个类的 实例变量会是NULL。下面看代码。
Java代码 public class A { private static A a = new A(); private B b = B.getInstance(); private A() { } public static A getInstance() { System.out.println("A被调用"); return a; } public void test() { System.out.println(b); } } public class A { private static A a = new A(); private B b = B.getInstance(); private A() { } public static A getInstance() { System.out.println("A被调用"); return a; } public void test() { System.out.println(b); } } Java代码 public class B { private static B b = new B(); private A a = A.getInstance(); private B() { } public static B getInstance() { System.out.println("B被调用"); return b; } public void test() { System.out.println(a); } } public class B { private static B b = new B(); private A a = A.getInstance(); private B() { } public static B getInstance() { System.out.println("B被调用"); return b; } public void test() { System.out.println(a); } } Java代码 public class Test { /** * @param args */ public static void main(String[] args) { B b = B.getInstance(); b.test(); System.out.println("=========="); A a = A.getInstance(); a.test(); //A a = A.getInstance(); //a.test(); //System.out.println("=========="); //B b = B.getInstance(); //b.test(); //System.out.println("=========="); } public class Test { /** * @param args */ public static void main(String[] args) { B b = B.getInstance(); b.test(); System.out.println("=========="); A a = A.getInstance(); a.test(); //A a = A.getInstance(); //a.test(); //System.out.println("=========="); //B b = B.getInstance(); //b.test(); //System.out.println("=========="); } } 得到的结果是: B被调用 A被调用 B被调用 A@35ce36 ========== A被调用 null 我原本在第一个getInstance的时候会出现 递归调用初始化 而 死锁的问题。但是没有,你知道JVM对于 构造方法的初始化是如何实现的。大家说说。 |
|
IcyFenix
2011-04-09
大致的执行过程如下,本来想直接贴Javap的字节码了事的,不过整理了一下后发现贴了估计也看不清楚,所以过程还是用中文大致写了一些:
这样写应该比较好懂了吧? |
|
Anddy
2011-04-09
如果你的想法跟我一样,看看我的分析流程,就一下子明白。
B--> B.getInstance() --- new B() | | | | | | new A() < ---- A.getInstance() 在new A() 中调用 B.getInstance(),return b ; 但是 b是静态成员,在B类加载的时候已经记录在静态存储区 【只是值为null】。 不会在去调用B.getInstance() 方法, 所以这个死锁不存在。 |
|
xgj1988
2011-04-10
IcyFenix 写道 大致的执行过程如下,本来想直接贴Javap的字节码了事的,不过整理了一下后发现贴了估计也看不清楚,所以过程还是用中文大致写了一些:
这样写应该比较好懂了吧? 但是虚拟机中一个类(<class,classloader>为一个类)只会初始化一次。 忘了这个,谢谢你的讲解。 |
|
lvjun106
2012-03-20
楼主试试把单例换成这种形式,就会出现循环调用且最终死锁。
getInstance() { if(instance == null) instance = new Instance(); return instance; } |
|
lvjun106
2012-03-20
刚看了一下楼上的时间,竟然去11年了。。
差不多一年了,怎么这种贴子也会在首页?? |
|
RednaxelaFX
2012-03-21
lvjun106 写道 刚看了一下楼上的时间,竟然去11年了。。
差不多一年了,怎么这种贴子也会在首页?? 其实我也是同样有疑问。之前就发现这帖在首页了,但我没办法把它弄下去… |
相关讨论
相关资源推荐
- Apache启动失败出现的问题及解决方案
- 通过IP地址不能访问Apache 解决方法
- 操作:Apache服务器搭建
- 修改APACHE中,关于主机IP地址修改的问题
- 使用CDN之后APACHE日志记录中IP地址不正确的解决方案
- apache正常运行(无报错),localhost 和本机 ip 均无法访问。以及443端口冲突解决。
- apache配置虚拟主机(实现一个ip对应多个站点)设置内部的访问控制(基于ip和基于用户)
- Weblogic下使用Apache插件中转后,远程IP地址不正确解决办法
- 利用URL Rewrite修改header头中的Server信息
- apache代理解决Javascript跨域问题