读书人

帮小弟我看一下下面这个单键模式为什

发布时间: 2013-03-26 09:54:33 作者: rapoo

帮我看一下,下面这个单键模式为什么不对?
//单键模式
class A{
private static A a;
private void A(){
}
public static synchronized A getA(A a){
if(a == null){
a = new A();
}
return a;
}
}


public class fSingletonctory {
A a = new A();
A b = new A();
System.out.println(a==b);
}


运行结果是false,为什么会是这样?如何改正?谢谢了


[解决办法]
亲,你的程序写的有问题。。。
private void A(){} 看清楚这个方法,它不是构造函数,应该是private A(){}
其次public static synchronized A getA(A a){}方法一点意义也没有,将参数去掉。
完整代码。

public class A {
private static A a;
private A() {};

public static synchronized A getA() {
if (a == null) {
a = new A();
}
return a;
}
}

像这样使用
Demo37 a = Demo37.getA();
Demo37 b = Demo37.getA();
System.out.println(a ==b);

[解决办法]
private void A(){
}
这个不是构造方法,楼上的人说了。
还有,你的构造方法都定义成private了,就是不让在创建实例的时候用new关键字。应该
A a = A.getA();//是的那个getA方法的参数可以不要
A b = A.getA();
这样看看a==b
[解决办法]
单例模式有三种实现方式:

/**
* 方法一:
* 对象延迟初始化,第一次获取对象时进行初始化。但是每次获取对象都会进行同步。同步会给系统增加开销。
*/
public class Singleton {

private static Singleton uniqueInstance;

private Singleton(){}

public static synchronized Singleton getUniqueInstance(){
if(uniqueInstance==null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}


/**
* 方法二:
* 静态初始化器中创建单例,初始化类时即对对象初始化,即使当前没有用到对象。会增加初始化的开销。
*/
public class Singleton {
private static Singleton uniqueInstance= new Singleton();

private Singleton(){}

public static Singleton getUniqueInstance(){
return uniqueInstance;
}
}

/**
* 方法三:
* 双重检查加锁,对象延迟初始化,并且保证只有第一次获取对象时同步。
*/
public class SingletonDoubleCheckedLocking {
private volatile static SingletonDoubleCheckedLocking uniqueSingleton;

private SingletonDoubleCheckedLocking(){}

public SingletonDoubleCheckedLocking getInstance(){
if (uniqueSingleton==null) {
synchronized (SingletonDoubleCheckedLocking.class) {
if (uniqueSingleton==null) {
uniqueSingleton = new SingletonDoubleCheckedLocking();
}
}
}

return uniqueSingleton;
}
}

如果获取单例对象所增加的额外开销(如:初始化开销、同步开销)不是系统主要的负担的话。方法一和方法二均可以放心使用。

至于你的问题,首先构造方法应该是私有的。你的“private void A()” 不是构造方法,因为有返回值类型。
其次获取实例应该由程序中提供的全局访问点来获取。
[解决办法]
楼上正解。单例模式么。都用getA()方法获得对象,这样a==b为true,因为引用了同一对象

读书人网 >J2SE开发

热点推荐