单例模式是最常用的JAVA设计模式之一,工作生活中会遇到,求职面试时可能也会问到,现重温回顾并记录下来,以免以后老了忘记了。
举斤例子:
听歌时,播放器是一种单例模式:听一首歌时,播放器播放歌曲声音,当切换另一首歌时是不会重新再打开一个播放器窗口的,而是直接在当前窗口切换歌曲;windows任务管理器也是一种单例模式;QQ和同一个好友聊天时打开的聊天窗口只会有一个,不会再开一个聊天窗口;java.lang.Runtime也是一种典型的单例模式 等等。
单例模式(Singleton)确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。(即类只能有一个实例,且必须是自己创建自己的唯一实例同时必须为其他对象提供这一实例)。
组成部分:
1.私有构造方法:防止外部实例化,只能内部自己实例化。
2.静态变量:利用一个静态变量来记录Singleton的唯一实例。
3.公有静态方法:通过该静态方法获取Singleton实例。
懒汉式单例:
/**
* 懒汉式单例
* @author 季先森
* ps:
* 懒汉式是一种延迟加载(Lazy Loading)的方式,即实例对象的创建是到第一次调用getInstance()方法时再完成,但在多线程中不能保证线程安全。
*/
public class LanhanSingleton {
//声明一个静态变量 记录Singleton类的唯一实例
private static LanhanSingleton lanhanSingleton;
//声明私有构造 外部不可实例化
private LanhanSingleton() {};
//外部对象通过调用此静态方法来获取实例对象
public static LanhanSingleton getSingleton(){
//方法内部自己管理实例,始终保证只有一个实例。 如果还没有实例,则创建实例,再返回实例
if(lanhanSingleton == null){
lanhanSingleton = new LanhanSingleton();
}
return lanhanSingleton;
}
}
饿汉式单例:
/**
* 饿汉式单例
* @author 季先森
* ps:
* 饿汉式在Singleton类加载的时候就实例化了对象,解决了线程同步问题,但较耗资源没有做到懒加载(Lazy Loading)的效果
*/
public class EhanSingleton {
//声明一个静态变量 记录Singleton类的唯一实例
private static EhanSingleton ehanSingleton = new EhanSingleton();
//声明私有构造 外部不可实例化
private EhanSingleton() {};
//外部对象通过调用此静态方法来获取实例对象
public static EhanSingleton getSingleton(){
return ehanSingleton;
}
}
测试:
public class TestSingleton {
public static void main(String[] args) {
//获取两个实例
LanhanSingleton s1 = LanhanSingleton.getSingleton();
LanhanSingleton s2 = LanhanSingleton.getSingleton();
//打印是否是同一实例
System.out.println(s1 == s2);
}
}
测试结果:
总结:
饿汉式单例从资源利用的角度来看,肯定会比懒汉式单例差些,但是反观从时间和反应速度上,却比懒汉式单例好些。
其他方式也可实现单例模式,如枚举、静态内部类等方式。