- 定义
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 - 实现
public class Singleton{
//一个私有的静待变量保存类的实例,不可直接访问和修改
private static Singleton instance= new Singleton();
//私有化构造函数,不可以被外部条用创建实例
private Singleton(){}
//唯一接口获取单例的对象
public static Singleton getInstance(){
return instance;
}
/**
*类的其他成员
**/
}
首先将构造函数房屋内控制为private ,只能为类内调用实例化,这样其他类就没办法实例化该对象了。
其次,定义一个保存唯一实例的变量,必须为类变量,用于保存唯一实例对象。
接下来提供一个接口用于获取该唯一实例。
比如该类,static修饰的类变量instance在类加载初始化阶段就得到一个实例,保存在方法区,执行堆中唯一的实例对象,由于直接保存在方法区,又提供一个静态的方法访问方法所以每次访问该类的实例都会获取到保存方法区的类变量instance值,而该值指向堆中的一个对象,类变量instance值值是唯一的(因为类在方法区是为唯一的)所以实例也是唯一的。
上面的方法线程安全的,但是只要类加载了就不管用不用都会创建一个对象,浪费空间即不支持 Lazy 初始化,所以就产生了一下支持Lazy初始化的实现方法。
——————————————————————————————————————————————
public class Singleton{
//一个私有的静待变量保存类的实例,不可直接访问和修改
private volatile static Singleton instance;
//私有化构造函数,不可以被外部条用创建实例
private Singleton(){}
//唯一接口获取单例的对象
public static Singleton getInstance(){
//使用时如果不存在则先初始化,由于为了保证只创建一个对象,进行加同步锁
if(instance = null){
synchronized(Singleton.class){
if(instance = null)
instance = new Singleton;
}
}
return instance;
}
/**
*类的其他成员
**/
}
这种实现方式在需要获取对象的时候才对类进行实例化,即实现了Lazy初始化,为了线程安全即无论几个线程同时访问都只能实例化一个对象需要加同步锁,实例对象的类变量需要用volatile修饰保证一个线程实例化后其他线程可见 。
这种方式虽然实现了Lazy初始化但是由于加同步锁会影响一些性能,鱼和熊不可兼得也
————————————————————————————————————————
还有一种常见的实现方法是,通过建立内部类,只有当使用到时内部类才会被加载,即通过延迟类的加载来实现Lazy初始化的作用,又是对线程安全的
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}