参考:https://www.cnblogs.com/cielosun/p/6582333.html
一、使用场景
需要某个类只保留一个对象,如数据库连接、网络连接、线程池等。
二、单例模式特点:
- 只能有一个实例
- 单例类必须创建自己的唯一实例
- 单列类向其他对象提供这一实例
三、单例模式与静态类对比
- 单例可以继承与被继承,方法可以重写。静态类不行
- 单例产生的对象常驻内存。静态类对象执行后会被释放,被GC清理
- 单例模式可以延迟加载,静态类在第一次运行时被初始化。
- 需要维持特定状态时使用单例模式,仅用于全局访问时使用静态类。
四、单例模式的实现
- 懒汉模式
- 饿汉模式:
- 【1】直接在运行这个类的时候进行一次loading,之后直接访问
- 【2】没有起到lazy 加载的效果
- 【3】与静态类相比:只多了一个内存常驻
- 静态类内部加载:
- 【1】静态内部类不会在单例加载时就加载,达到了类似懒汉模式的效果
- 【2】线程安全
- 枚举方法:
- 【1】自由序列化
- 【2】只有一个实例
- 【3】线程安全
/** 一、饿汉式
* 1.没有起到lazy loading的效果
* 2.只比静态类多个常驻内存的作用
* */
class HungrySingleton {
//饿汉式
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getHungrySingleton(){
return hungrySingleton;
}
}
/***
* 二、懒汉式
*/
class LazySingleton{
//懒汉式
private static LazySingleton lazy = null;
private LazySingleton(){}
// 考虑线程安全,可能多个访问者访问时,加锁
public static synchronized LazySingleton getLazy(){
if(lazy == null){
lazy = new LazySingleton();
}
return lazy;
}
}
/**静态类内部加载*/
class SingletonStaticClass{
private static class SingletonHolder{
private static SingletonStaticClass instance = new SingletonStaticClass();
}
public SingletonStaticClass() {
}
//不会再单例加载时就加载,调用该方法时才加载,达到了类似懒汉模式的效果
public static SingletonStaticClass getInstance(){
return SingletonHolder.instance;
}
}
/**枚举方法*/
class Resource{
// 为网络连接,数据库连接,线程池等等
}
enum SingletonEnum{
INSTANCE;
private Resource instance;
SingletonEnum(){
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}
public static void main(String[] args) {
SingletonEnum.INSTANCE.getInstance();//调用枚举的单列模式
}