这个 Java 单例能否在 WebSphere 6 中反复重建?

2022-09-04 05:18:27

我正在尝试跟踪我们系统中的问题,下面的代码让我担心。以下情况发生在主 servlet 中的 doPost() 方法中(名称已更改以保护有罪者):

...
if(Single.getInstance().firstTime()){
   doPreperations();
}
normalResponse();
...

单例“单例”如下所示:

private static Single theInstance = new Single();

private Single() {
...load properties...
}

public static Single getInstance() {
    return theInstance;
}

如果将其设置为使用静态初始值设定项,而不是在 getInstance() 方法中检查 null theInstance,是否可以一遍又一遍地重新构建?

PS - 我们在 Java 1.4 上运行 WebSphere 6 和 App


答案 1

我在Sun的网站上找到了这个:

由不同的类装入器同时装入多个单例

当两个类装入器装入一个类时,您实际上有该类的两个副本,并且每个副本都可以有自己的 Singleton 实例。这在某些 servlet 引擎(例如 iPlanet)中运行的 servlet 中尤其重要,其中每个 servlet 默认使用自己的类装入器。事实上,访问联合单例的两个不同的 servlet 将获得两个不同的对象。

多个类装入器的发生频率比您想象的要高。当浏览器从网络装入类以供小程序使用时,它们会为每个服务器地址使用单独的类装入器。类似地,Jini 和 RMI 系统可以对从中下载类文件的不同代码库使用单独的类装入器。如果您自己的系统使用定制类装入器,则可能会出现所有相同的问题。

如果由不同的类装入器装入,则两个具有相同名称的类,甚至是相同的包名称,将被视为不同 - 即使实际上它们是完全相同的类。不同的类装入器表示区分类的不同命名空间(即使类的名称相同),因此这两个类实际上是不同的。(请参阅 参考资料 中的“作为命名空间机制的类装入器”。由于两个 Singleton 对象属于两个同名的类,因此乍一看似乎有两个相同类的单例对象。MySingleton

引文

除了上述问题之外,如果未同步,则也可能存在线程问题。firstTime()


答案 2

不,它不会一遍又一遍地构建。它是静态的,所以它只会被构造一次,就在Classloader第一次接触类的时候。

唯一的例外 - 如果您碰巧有多个类装入器。

(来自GeekAndPoke):

alt text


推荐