第一种形式 public class Singleton { private Singleton(){} private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } } 第二种形式: public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { if (instance==null) instance=new Singleton(); return instance; } }
class Single{ private Single(){}
private static final Single s1=new Single(); public static Single getSingleInstance(){ return s1; } public void Say(){ System.out.println("我开始说话了。"); }
}public class SingletonDemo { public static void main(String[] args) { Single s=Single.getSingleInstance(); s.Say(); }}
private static final Single s1=new Single(); 这里的final需要加吗?
class Single { public static Single instance = null; private Single() { } public static Single getInstance() { if (instance == null) { instance = new Single(); } return instance; } }
1楼的第二种形式是错的,应该使用double check进行判断。。至于第一种,下面的方式岂不是简洁?public class Singleton { private Singleton(){} public final static Singleton instance = new Singleton();
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
} 第二种形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance==null)
instance=new Singleton();
return instance;
}
}
class Single{
private Single(){}
private static final Single s1=new Single();
public static Single getSingleInstance(){
return s1;
}
public void Say(){
System.out.println("我开始说话了。");
}
}public class SingletonDemo {
public static void main(String[] args) {
Single s=Single.getSingleInstance();
s.Say(); }}
这里的final需要加吗?
class Single {
public static Single instance = null; private Single() {
} public static Single getInstance() {
if (instance == null) {
instance = new Single();
}
return instance;
}
}
private Singleton(){}
public final static Singleton instance = new Singleton();
}
1楼的第二种形式是错的,应该使用double check进行判断。。 不需要吧,应该不要double check进行判断,好像c++是需要的,
上次看阎宏的那本设计模式的书,他说进行double check在java中
是多余的,不知道正确否???
你这样写怎么生成Singleton的实例?
不是多余的,而是 double-checked 在 Java 中是无效的,也就是说这段代码在
Java 中可能起不到只产生单个实例的作用:public class Foo { private static Foo instance = null; private Foo {
} public Foo getInstance() {
if (instance == null)
synchronized(this) {
if (instance == null)
instance = new Foo();
}
return instance;
}
}至于这段代码为什么不起作用,或者说应在何种情况下如何让它起作用,呵呵,这个问题很复杂,
已经超出我的能力范围,详见下面的资料:The "Double-Checked Locking is Broken" Declaration
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.htmlDouble-Checked locking: Clever but broken
http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html不可否认 double-checked 是个了不起的做法,将初始化纳入到使用时,而且还巧妙地控制了多
线程访问的问题,但由于其的特殊性,再者对于现在性能越来越高的机器来说,这些延迟初始化的
所能提升的效率是微忽其微的了,建议采用 1 楼代码第一种形式强制初始化,因此在 Java 中不
需要去掌握 double-checked 的技巧,我想阎宏的观点应该是这样的。顺便提一下,1 楼代码的第二种形式是不可取的,由于在方法中加上了 synchronized 修饰,在
多线程访问时的效率是很低的,在并发访问时到这里都会阻塞掉,因此这种方式不可取。因此创建单例的方式有以下几种形式:1,1 楼代码方式一,即强制初始化;
2,1 楼代码方式二,即同步延迟初始化;
3,加上 volatile 关键字的 double-checked 延迟初始化(第一个连接结尾处有代码);
4,还有一种方式充分利用静态内部类的初始化顺序构建的,代码我想不起来了,有兴趣的话
可以看看 Effective Java 上的介绍,这也是一种安全的延迟初始化。
class Instance
{
private Instance() { }
private static Instance i = new Instance();
public static Instance getInstance() { return i; }
}public class Singleton
{
public static void main(String[] args)
{
Instance i1 = Instance.getInstance();
Instance i2 = Instance.getInstance();
System.out.println(i1 == i2);
}
}
/*output:
true
*/