单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
作用:1.节约内存资源,个人觉得这不是主要目的。
2.业务上只能有一个实例,当实例存在多个会引起程序逻辑错误的时候。如打印或者序列生成器。
实现:
1 第一种形式: 也是常用的形式。
public class Singleton {
private static Singleton instance = null;
private String name;
private Singleton() {
name = "123";
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
第二种形式:在自己内部定义自己的一个实例,只供内部调用
public class Singleton {
// 在自己内部定义自己的一个实例,只供内部调用
private static Singleton instance = new Singleton();
private Singleton() {
// do something
}
// 这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
第三种形式: 双重锁的形式。
public class Singleton {
private static Singleton instance = null;
private Singleton(){
//do something
}
public static Singleton getInstance(){
if(instance==null){
synchornized(Singleton.class){
if(null == instance){
instance = new Singleton();
}
}
}
return instance;
}
}
//这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。
要注意的是:单例模式中,除了实例变量,其他变量不需要也定义成静态的(static)
实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。