单例模式

单例模式的意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个
这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,
简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,
任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。

第一种形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Signgleton
{

//定义一个私有的静态全局变量来保存该类的唯一实例
private static Singleton instance=null;
//将构造函数私有化,保证外部不能用new来创建该类的实例。
private Singleton()
{

// do someting
}
//定义一个全局访问点,设置为静态的,这样不需要实例也能调用该函数。
public static Singleton getIntance()
{

//保证只能实例化一次,第二次调用该函数时,instance已经存在,不执行new操作。
if(instamce==null)
{
instance=new Singleton();
}
return instance;
}
}

这种形式在多线程的环境下会出现问题。如果线程A在if判断后中断,那么就有可能在中断期间,另一线程B执行getInstance函数,当A重新获得处理器后,会再次创建一个实例。

第二种形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton
{

//在自己的内部定义自己的一个实例,只供内部调用
private static Singleton instance=new Singleton();
private Singleton()
{

//do someting
}
//这里提供了一个供外部访问本class的静态方法
public static Singleton getInstance()
{

return instance;
}
}

这种形式可以有效的支持多线程,但即使未被调用,该类也存在一个实例。

第三种形式:双重锁的形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Singleton
{

private static Singleton instance=null;
private Singleton()
{

//do someting
}
//这里提供了一个供外部访问本class的静态方法
public static Singleton getInstance()
{

if(instance==null)
{
//synchronized 保证在同一时刻最多只有一个线程执行该段代码
synchronized(Singleton.class)
{
if(null==instance)
{
instance=new Singleton();
}
}
}
}
}

把同步放在if条件内部是为了提高效率,这样只有在第一次实例化的时候才有可能同步,实例化之后,如果再会有实例化,会直接被if阻拦。