解决的问题:
保证一个类在内存中的唯一性。
比如,必须要对于多个程序使用同一个配置信息时,就需要保证该对象的唯一性。
原理:
如何保证对象的唯一性呢?
- 不允许其他程序使用new创建该类对象
- 在该类中创建一个本类对象
- 对外提供一个公共方法,使其他程序可以获取该实例。
步骤:
- 私有化该类的构造函数
- 通过new在本类中创建一个本类对象
- 定义一个公共的方法,将创建的对象返回。
单利设计模式的分类:
1.饿汉式
//饿汉式 class Single{ //私有化该类的默认构造函数,使外部不能new该类对象 private Single() { } //创建一次该类对象 private static Single s = new Single(); //对外提供获取该对象的方法 public static Single getInstance(){ return s; } }class SingleDemo{ public static void main(String[] args){ Single s1 = SIngle.getInstance(); Single s2 = SIngle.getInstance(); System.out.println(s1==s2); } }
内存图解:
说明:
- main函数进栈,并执行第一句代码Single s1 = SIngle.getInstance(); ,创建s1引用
- 在方法区中加载Single类的方法,在非静态区有Single的构造函数,静态区有s成员变量、getInstance方法
- 在堆中创建一个Single对象,并让s指向该对象
- 执行Single s1 = SIngle.getInstance(); 赋值操作,使s1的值为s的值。
- s2同理,由于对内存中只有一个该类的对象,并使静态区的s指向它,因此s1和s2指向同一对象。
2.懒汉式
//l懒汉式 class Single{ //私有化默认构造函数 private Single(){} //声明一个该类的引用 private static Single s; //对外提供获取该类唯一对象的方法 public static Single getInstance(){ if(s==null) //如果s是第一次创建 s = new Single(); return s; } }
饿汉和懒汉模式的区别:
饿汉模式,类一加载对象就已经建立
懒汉模式,类加载时没有对象,只有调用了getInstance方法才创建对象,即延迟加载
饿汉模式效率比懒汉模式高,因为饿汉模式不像懒汉模式那样每次获取对象都做判断
懒汉模式在多线程中可能存在安全问题。