单例模式建议保证某个对象仅仅只有一个实例,当只有一个对象来协调整个系统的操作时,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例,总之,选择单例模式就是为了避免不一致状态,避免政出多头。
下面是单例模式的类图:包括的private和static修饰的实例instance、一个private的构造函数、一个static的getInstance函数
单例模式主要有三种:懒汉式单例、饿汉式单例、登记式单例三种
1、饿汉式单例:在类的初始化时候,自行创建了实例
class Singleton1{ public Singleton1() {}; //自行实例化 static private final Singleton1 instance = new Singleton1(); //获取唯一实例 public static Singleton1 getInstance(){ return instance; } }
2、懒汉式单例:在真正需要的时候在创建唯一实例
//线程安全之一 class Singleton3{ public Singleton3() {}; static private Singleton3 instance = null; //获取唯一实例 public static synchronized Singleton3 getInstance(){ if(null == instance){ return new Singleton3(); } return instance; } }
3、登记式单例:类似Spring,通过名字匹配获取唯一实例
class Singleton4{ public Singleton4() {}; static private Map<String, Singleton4> map = new HashMap<String,Singleton4>(); static{ Singleton4 single = new Singleton4(); map.put(single.getClass().getName(), single); } //根据名字获取唯一实例 public static synchronized Singleton4 getInstance(String name){ if(null == name){ name = Singleton4.class.getName(); System.out.println("name == null"+"--->name="+name); } if(null == map.get(name)){ try { map.put(name, (Singleton4)Class.forName(Singleton4.class.getName()).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); } public String about() { return "Hello, I am RegSingleton."; } }main函数:
public class MySingleton { public static void main(String[] args) { Singleton4 single4 = Singleton4.getInstance(null); Singleton4 single5 = Singleton4.getInstance(null); Singleton4 single6 = Singleton4.getInstance("aaa"); Singleton4 single7 = Singleton4.getInstance("bbb"); if(single4 == single5){ System.out.println("single4和single5是同一个实例"); }else{ System.out.println("single4和single5不是同一个实例"); } if(single6 == single7){ System.out.println("single46和single7是同一个实例"); }else{ System.out.println("single6和single7不是同一个实例"); } }输出结果:
name == null--->name=com.Singleton4 name == null--->name=com.Singleton4 single4和single5是同一个实例 single6和single7不是同一个实例