1、单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2、通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个方法访问该实例。
3、单例模式结构图
4、简单代码实现
Singleton类,定义一个getinstance操作,允许客户访问它的唯一实例,getinstance是一个静态方法,主要负责创建自己的唯一实例。
public class Singleton {
private static Singleton single;
private Singleton() {
// TODO Auto-generated constructor stub
}
public static Singleton getInstance() {
if(single==null) {
single=new Singleton();
}
return single;
}
}
客户端代码
public class Client {
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
if(s1==s2) {
System.out.println("是同一个实例");
}
}
}
5、单例模式因为Singleton类封装它的唯一实例,这样可以严格的控制客户怎样访问它以及何时访问。简单来说就是对唯一实例的受控访问。
6、多线程时的单例
public class MultithreadingSingleton {
private static MultithreadingSingleton instance;
private static final Object syncRoot=new Object();
private MultithreadingSingleton() {
// TODO Auto-generated constructor stub
}
public MultithreadingSingleton getInstance() {
synchronized (syncRoot) {
if(instance==null) {
instance=new MultithreadingSingleton();
}
return instance;
}
}
}
每次调用getInstance都需要加锁,影响性能。
7、双重锁定
public class DoubleLockSingleton {
private static DoubleLockSingleton instance;
private static final Object syncRoot=new Object();
private DoubleLockSingleton() {
// TODO Auto-generated constructor stub
}
//Double-Check——Locking 双重锁定
public DoubleLockSingleton getInstance() {
if(instance==null) {
synchronized (syncRoot) {
if(instance==null) {
instance=new DoubleLockSingleton();
}
}
}
return instance;
}
}
判断两次是因为第一个判断可能前后通过不止一根线程,内部加锁能够保证只创建一个实例。
8、静态初始化单例模式
//防止派生时产生实例
public final class StaticSingleton {
private static final StaticSingleton instance=new StaticSingleton();
private StaticSingleton() {
// TODO Auto-generated constructor stub
}
public static StaticSingleton getInstance() {
return instance;
}
}
9.1、静态初始化的方式是在自己被加载时就将自己实例化,成为饿汉式单例。
9.2、前面在需要引用时才进行初始化成为懒汉式单例模式。