关于多例模式-from单例模式

04-03-23 airport
第二种形式:

public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     

  //使用时生成实例,提高了效率!

  if (instance==null)

    instance=new Singleton();

  return instance;   }

}

使用Singleton.getInstance()可以访问单态类。

上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

------------

以上引用jdon.com

请问如何写一个测试例子,能够证明可以生成多例模式,我现在某种情况下需要多例!也就是大多数情况需要利用单例模式调用资源,但是如果资源被占用的时候,需要从新生成一个对象,去掉synchronized可以?能不能给个测试的例子!

airport
2004-03-23 17:30
现在的具体情况是这样的,我有点被单例模式搞糊涂了。

我有一个Class A的类,这个类每个page都会用到。

所以我希望用单例模式防止过度重建对象。

现在的问题是:

1、如果已经有page使用的时候,要从新new一个。

2、如果没有page没有在用的时候,可以从新使用。

我怎么感觉好像需要对象池来管理了,简单的单例模式不知道是不是可以?

banq
2004-03-23 18:55
是的,需要使用池模式来解决,池中每个实例是单例。

banq
2004-03-23 18:56
池中每个实例是单例。这句不准确,你所要的就是object pool

airport
2004-03-23 19:40
有没有简单的对象池管理框架,我不想用EJB的

另外,能不能测试一个例子,证明你的多例模式的存在?

static的应该只能存在一个实例呀

mochow
2004-03-24 17:42
你的情况是很多page都会用到这个类,并且在整个周期中,该类可以有多个实例,所以从根本上你选择单例模式是错误的。

如果想重用那就建一个对象池,在池中对这些对象的生长和销毁进行处理。

mochow
2004-03-24 18:33
简单的写了一些多例模式的代码,不一定正确啊,思路是

每次要用到Cat类时,就用getInstance()去取,这里定义

最多有10个实例,如果发现Vector中没有实例,则创建一个

并使用,同时用setIsUse()方法设置isUse为true,使用完

毕就设置该变量为true(这只是简单的表示,不一定好)。

如果实例存在,则判断是否被使用,如果没有则返回,如果

被使用,则继续判断Vector中下一个实例,如果10个实例都

被使用,则返回null,让新的page等待或者进行别的处理。

public class Cat {
    private static Vector instance= new Vector(10);
    //表示该实例是否被使用 
    private boolean isUse = false;
    private Cat() {
    }
    static public synchronized Cat getInstance(){
	Cat obj = null;
	for(int i = 0; i < instance.size();i++){
	    obj = (Cat)instance.elementAt(i);
	    if(obj==null){
		obj = new Cat();
		instance.setElementAt(obj,i);
		return obj;
	    }
	    else if(!obj.getIsUse()){
		return obj;
	    }
	
	}	
	//返回null表示目前对象池里没有空闲的对象
	return null;	
    }
    
    public boolean getIsUse(){
	return isUse;
    }
    public void setIsUse(boolean isUse){
	this.isUse = isUse;
    }
}
<p>

airport
2004-03-25 11:18
按照你的代码,如果我在使用Cat对象的时候每次都要先setuse=ture

页面结束以后再setuse=false,这样不是很好.

不过你给我了一些思路,我想没必要用单例模式,自己建立一个管理池

设定大小以后就行轮循

public class STPoolManager {

private static final int loop = 10;

private static int loopAt = 0;

private static Vector instance = new Vector(loop);

private STPoolManager() {

for(int i=0 ; i<loop ; i++){

SuperTemplate obj = new SuperTemplate();

instance.setElementAt(obj,i);

}

}

public static synchronized SuperTemplate factory(){

SuperTemplate obj = (SuperTemplate)instance.get(loopAt);

if(loopAt == loop-1)

loopAt = 0;

else

loopAt++;

return obj;

}

}

airport
2004-03-25 11:18

public class STPoolManager {
    private static final int loop = 10;
    private static int loopAt = 0;
    private static Vector instance = new Vector(loop);
    private STPoolManager() {
        for(int i=0 ; i<loop ; i++){
            SuperTemplate obj = new SuperTemplate();
            instance.setElementAt(obj,i);
        }
    }

    public static synchronized SuperTemplate factory(){
        SuperTemplate obj = (SuperTemplate)instance.get(loopAt);
        if(loopAt == loop-1)
            loopAt = 0;
        else
            loopAt++;
        return obj;
    }

}

airport
2004-03-25 12:21
不过还是没有解决资源在使用中的情况!

mochow
2004-03-25 17:07
我看了你的代码之后,觉得你好像没有理解我的本意。

isUse的用法正如我自己提到的,只是一个方便的表示,

你可以考虑其他的表示,既然用到这个类,你肯定要执行某些逻辑

在执行这些逻辑的时候,开头和结束可以考虑占用和释放Cat类的实例,

并不一定要在page的代码里来操作啊。

至于你怎么占用和释放,采取什么方式就结合你自己的实际场景采取

相应的措施。

主要的关于Cat的资源控制是在那个静态方法里面。

wzbwambition
2004-03-25 17:18
其实你这样写,还是没办法避免当你的loopAt已经到10了,instance[0]却还没有释放,还是需要等待啊。

mochow
2004-03-25 17:29
另一方面,防止过度的创建对象,并不一定意味着已经创建的对象要一直的存在,可以定义一个集合,规定同时最多可以有一定数量的对象存在,当用完这个对象的时候,就把它从集合中remove掉,从而可以创建相应数量的新对象。

airport
2004-03-25 21:57
如果是池的话,肯定是需要保持一定数量的操作.

不过我现在考虑了一下,如果创建对象不怎么占用

系统时间的话,也许new一个就可以了,只不过java

的垃圾回收不知道是如何进行的,如果很慢的话,那

么在一定时间内就会有大量的对象产生,就有必要

控制如何创建对象了.

xuzhenhua21
2004-03-27 14:13
java的垃圾机制是基于线程的,是优先级最低的线程,(为0)

所以很久才会回收垃圾。(读<<java夜未眼>>得知

猜你喜欢
2Go 1 2 下一页