0

早上好。

我目前正在开发一个 Java Web 服务项目,该项目部署在 Apache Tomcat 7 服务器上。为了项目的需要,我需要在内存中维护一个全局(在 WS 线程中,由每个请求创建)对象。因此,我尝试按如下方式实现单例设计模式:

public class SingletonDesign {
    private static boolean _instanceFlag = false;
    private static final SingletonDesign _instance = new SingletonDesign();
    private static GlobalObject _myGlobalObject;

    private SingletonDesign() {
        if(_instanceFlag == false) {
            _myGlobalObject = new GlobalObject();
            _instanceFlag = true;
        }
    }

    public static GlobalObject getModel() {
        if(_instanceFlag == false) {
            _myGlobalObject = new GlobalObject();
            _instanceFlag = true;
        }
        return _myGlobalObject;
    }

    public static int parseModel() {
        if(_instanceFlag == false) {
            _myGlobalObject = new ItemSimilarityModel();
            _instanceFlag = true;
        }
        int val = _myGlobalObject.parseFromFile();
        return val;
    }
}

我知道每次完成请求时,都会在我的 Web 上创建一个新线程——服务类(对象)。我的目标是在所有线程中拥有一个全局 SingletonDesign 对象,该对象在内存中保持活动状态,并且只创建一次。尽管上述设计似乎符合我的预期,但我不确定它是否正确。所以这些是我的问题:

1)为什么SingletonDesign对象的方法需要是静态的?(我试图将它们定义为非静态的,但我的 Singleton 对象未正确初始化)。

2)以上设计见于单例设计模式的维基百科页面。让我困惑的部分是 _instance 字段的初始化,我在其他 Singleton 实现中也看到过。为什么我们需要那个对象?

3)我的对象在服务器停止之前是否保持活动状态?我做了一些测试,似乎它还活着,但我必须 100% 确定。

感谢您的时间与兴趣。

4

2 回答 2

2

_instance字段包含您的单身人士。您需要一个静态getInstance()方法,而您的其他方法将是实例方法。我认为你根本不需要这个_instanceFlag领域。

然后你会这样称呼它:

SingletonDesign.getInstance().getGlobalObject();

不过,请记住,很多人(包括我自己)认为 Singleton 是一种代码气味。此外,这种设计不被认为是在 Java 中实现单例的最佳方式,cfr:在 Java中实现单例模式的有效方法是什么?

只要它的类加载器还活着,这个对象就会一直活着。

于 2012-09-03T11:15:48.170 回答
1

1) 你在单例中真正需要的唯一静态方法是返回单例实例的方法。该方法必须是静态的,因为您不能实例化单例,因此该方法必须属于类而不是对象。

2)一个可能更容易开始的简化版本:

public class MySingleton {

    private static MySingleton instance = null;
    private static String aString = null;

    private MySingleton( {
        aString = new String("Hello, world");
    }

    public static MySingleton getInstance() {
        if (instance == null) {
            instance = new MySingleton();
        }

        return instance;
    }

    public string getMyString() {
        return aString;
    }
}

3) 据我所知,只要 JVM 运行,它就会一直存在。

作为提示,如果您在返回实例的方法中执行某种初始化代码,我建议您也将该方法声明为同步。

于 2012-09-03T11:13:09.233 回答