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 为真,就会实例化两次。
二:线程安全
1class 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.普通实现方法,每次都需要检查类的对象是否已经存在,增大开销,建议使用静态初始化方法。