关于单例的一个问题

2015-02-24 13:38:50 +08:00
 georgetso

public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}􏳅
􏳅 􏳅 public static Singleton getInstance() {
return instance; 􏳅 􏳅
􏳅􏳅 }
}

上面的例子,书里解释道:
单例在类被􏰂􏳕􏰂􏳕加载的时候实例化,这􏰼样多次加载􏰂􏳕会造成􏰅多次实例化。

类被多次加载的意思是什么?多个线程里被加载?
既然已经限定了 static 关键字,那 instance 应该被存储在全局和静态存储区里,不应该被多次事例化啊

3046 次点击
所在节点    程序员
13 条回复
Mirana
2015-02-24 13:41:07 +08:00
每次实例化的时候都重新执行一次把
georgetso
2015-02-24 13:48:30 +08:00
@Mirana 实例化执行的是 Singleton() 方法。我问的是类被加载。你看错了吧
mhycy
2015-02-24 13:53:24 +08:00
记忆中这是未定义行为,应该在get的时候判断是否为null并初始化
Mirana
2015-02-24 14:23:09 +08:00
@georgetso 哦,ioc容器给一个类名 加载一个类的实例 应该是类的加载把
hitsmaxft
2015-02-24 14:25:32 +08:00
static {} 段的内容classloader在加载class的过程中被执行,多个classloader重复加载同一个class就就行多次。
hitsmaxft
2015-02-24 14:27:16 +08:00
@Mirana 你说的是对象实例化,static和实例无关,只和类型相关
georgetso
2015-02-25 09:49:19 +08:00
@hitsmaxft 书中使用java作为示例。这个问题是否可能因为语言的不同出现不同的结果?例如,如果java和c++的 class loading 机制不一样的话会怎么样?
hitsmaxft
2015-02-25 10:03:17 +08:00
@georgetso 单例的本质是资源全局唯一。应该说这段代码是利用了java的static实现了单例。所以不同语言确实需要入乡随俗
ob
2015-02-25 10:45:24 +08:00
不同的语言对内存的管理上应该都是类似,楼主提的问题,下面我说下我的理解:
首个类和对象的区别,楼主肯定是知道的。
那一个类,肯定是可以被创造出多个对象的,也就是被实例化多次。
至于楼主说的static关键字,以及上面代码生成的单例。只能说在类被实例化多次的时候,用到的引用都是指向同一个对象。也就是实例化多次其实返回的是对一个对象。所以叫单例。
georgetso
2015-02-25 11:07:45 +08:00
@ob 看了您的回答,我还是没弄明白。类被实例化的情况完全不在我的问题中。我询问的是类加载的问题。
lip
2015-02-25 11:26:13 +08:00
private static Singleton instance = new Singleton();
这个是静态的,会在classloader第一次load这个class的时候执行,而且仅在这个时候执行。
之所以这样实现是单例,是因为一般情况下,按照java的类加载机制,一个类只会被一个classloader加载,而且仅加载一次,因此在一个jvm里面仅有这一个实例。
文中说的多次加载会造成多次实例化是指的非一般情况下,可能有多个classloader都加载这个class,因此每个classloader加载的时候都会实例化一个实例,也就是所谓的多次实例化。非一般情况常见的是那些web容器,比如tomcat,was;eclipse的插件实现也用了一堆的classloader,都会有这种现象
Osake
2015-02-25 15:29:56 +08:00
@lip 说的应该是对的 而且如果多个classloader加载同一个class的情况时,会产生不同的class,因为jvm判断一个class是不是唯一除了通过类名外还要判断类的加载器是不是同一个,也就是说如果一个类被不同的加载器加载,那么他们的实例是不同的(互相赋值会抛出运行时异常 ClassCastException)。
georgetso
2015-02-25 16:18:15 +08:00
@lip
@Osake 感谢两位。java是虚拟机语言,那么 c++ 这种编译语言是否有可能出现这种情况?例如多线程之类的情况。我明白这个需要看 c++ 的编译器的实现方案,不过就大体而言,编译语言一般来讲是否会出现这种情况?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/172459

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX