帮我看一下,下面这个单键模式为什么不对?
//单键模式
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,为什么会是这样?如何改正?谢谢了
------最佳解决方案--------------------单例模式有三种实现方式:
/**
* 方法一:
* 对象延迟初始化,第一次获取对象时进行初始化。但是每次获取对象都会进行同步。同步会给系统增加开销。
*/
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()” 不是构造方法,因为有返回值类型。
其次获取实例应该由程序中提供的全局访问点来获取。
------其他解决方案--------------------亲,你的程序写的有问题。。。
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
------其他解决方案--------------------楼上正解。单例模式么。都用getA()方法获得对象,这样a==b为true,因为引用了同一对象
------其他解决方案--------------------