来源于http://www.blogjava.net/sunsjorlin/archive/2007/12/28/171033.html
1.保证一个类只有一个实例的机制.
2.站在类的设计者的角度,强制使一个类只能有一个实例,而不是站在类的使用者角度。
一:简单实现
//简单模式
class singletonOne


{
//静态变量
private static singletonOne stOne = null;
//私有构造器

private singletonOne()
{}
//获取实例方法
public static singletonOne getInstance()

{
if(stOne == null)

{
stOne = new singletonOne();
}
return stOne;
}
}
优点是简单,清淅明了。缺点是在多线程环境下不能保证只实例化一次。如A,B两线程,同时判断stOne == null 为真,就会实例化两次。
二:线程安全
1
class singletonTwo
2

{
3
//静态变量
4
private static singletonTwo stTwo = null;
5
//私有构造器
6
private singletonTwo()
{}
7
//线程对象
8
private static Object obj = new Object();
9
10
//获取实例方法1 完全保证线程安全,但增大了不必要的线程开销
11
public synchronized static singletonTwo getInstance()
12
{
13
if(stTwo == null)
14
{
15
stTwo = new singletonTwo();
16
}
17
return stTwo;
18
}
19
20
//获取实例方法2 当其它类或线程第二次来调用时,减少相应线程开销
21
public static singletonTwo getInstanceTwo()
22
{
23
if(stTwo == null)
24
{
25
synchronized(obj)
26
{
27
if(stTwo == null)//此处判断的作用在于:当第一次初始化时即有多个线程进入第一个 stTwo == null 的判断块,同时等待obj的线程释放。
28
{
29
stTwo = new singletonTwo();
30
}
31
}
32
}
33
return stTwo;
34
}
35
}
优点为:因为实例化语句处于getInstance方法里,即当需要一个singleton实例时,才会产生。这种方法称为惰性实例化,惰性实例化避免了在不必要一个实例时产生了实例对象。
三:静态初始化
//直接实例化一个静态实例
class staticSingletonOne


{
private static staticSingletonOne staticStOne = new staticSingletonOne();
public static int num = 0;
private staticSingletonOne()

{
num = 10;
}
public static staticSingletonOne getInstance()

{
return staticStOne;
}
public static void SystemOutNum()

{
System.out.println(num++);
}
public static void main(String[] str)

{
staticSingletonOne.SystemOutNum();
staticSingletonOne.SystemOutNum();
staticSingletonOne.SystemOutNum();
staticSingletonOne.SystemOutNum();
}
}

//通过静态代码块实例化一个静态实例
class staticSingletonTwo


{
private static staticSingletonTwo staticStTwo;
public static int num = 0;
private staticSingletonTwo()

{
num = 10;
}
static

{
staticStTwo = new staticSingletonTwo();
}
public static staticSingletonTwo getInstance()

{
return staticStTwo;
}
public static void SystemOutNum()

{
System.out.println(num++);
}
public static void main(String[] str)

{
staticSingletonTwo.SystemOutNum();
staticSingletonTwo.SystemOutNum();
staticSingletonTwo.SystemOutNum();
staticSingletonTwo.SystemOutNum();
}
}

//此两个类对于 singleton这个模式而言,产生的对象是没有任何区别的。
//同样只执行了一次staticStTwo = new staticSingletonTwo(),但输出的数字却有戏剧性的区别,staticSingletonOne输出的为0,1,2,3 而staticSingletonTwo输出的却为10,11,12,13。
//根本原因在于:staticSingletonOne在实例化对象时将 num赋为10,随后在执行静态变量初始化时又赋为了0。而在staticSingletonTwo, num 变量与实例化语句同处于静态变量中,先num=0,然后才赋num=10操作。
要点:
1.singleton不要支持序列化,避免出现多个实例,与singleton模式理念冲突
2.singleton只考虑到了对象的创建管理,没有考虑到对象的销毁管理,在支持垃圾回收的平台下(.net,java),一般不需要考虑对对象销毁管理作特别的处理。
3.模式的核心为:控制类的使用者对类的实例方法任意使用并使最终只产生一个实例。
4.普通实现方法,每次都需要检查类的对象是否已经存在,增大开销,建议使用静态初始化方法。
posted on 2007-12-28 14:39
Crying 阅读(241)
评论(0) 编辑 收藏 所属分类:
模式