一.什么是单例模式
有过项目开发经验的大佬肯定都知道也用过这个广为程序猿所知的设计模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例,即一个类只有一个对象实例。在实现单例模式的时候要记住,由于要保证实例只有一个,自己来完成实例的创建,所以要提供无参构造方法(否则系统会提供默认的构造方法,默认是public,会导致其他类可以通过默认构造方法获取实例,破坏单例模式只有一个实例的要求),并且为private类型,那么其他类无法访问,也无法创建实例,只能通过单例模式获取。
二.单例模式的两种基本分类
1.饿汉式:
package zwk.single;
public class SinglePattern {
// 饿汉模式
private static SinglePattern singlePattern = new SinglePattern();
// 构造方法,注意是private类型,保证一个实例
private SinglePattern() {
}
public static SinglePattern getInstance() {
return singlePattern;
}
饿汉模式在类加载的时候就已经完成了实例的创建,所以不存在线程同步的问题,但是如果没有用到就已经创建了实例,大大浪费了内存
2.懒汉式:
package zwk.single;
public class SinglePattern {
// 饿汉模式
private static SinglePattern singlePattern ;
// 构造方法
private SinglePattern() {
}
public static synchronized SinglePattern getInstance() {
if(singlePattern!=null)
singlePattern= new SinglePattern();
return singlePattern;
}
}
实现效率太低,,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步
三.真正开发中能用的单例模式的演化版本
1.静态内部类(这种方法我第一次见到真的是在项目中,可能是我见识少吧。。。。)
package zwk.single;
public class SinglePattern {
// 构造方法
private SinglePattern() {
}
//静态内部类,外部类不可访问,用于创建实例
private static class SinglePatternInstances{
private static final SinglePattern instacne=new SinglePattern();
}
//用于对外提供实例
public static SinglePattern getInstance() {
return SinglePatternInstances.instacne;
}
}
这种方法创建了一个静态内部类,用于创建实例对象,然后提供一个公有的方法,用于对外提供实例,好处:静态内部类方式在SinglePattern类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SinglePatternInstances类,从而完成SinglePattern的实例化。
2.双重检查(传说中的Double-Check):
package zwk.single;
public class SinglePattern {
private static volatile SinglePattern single;
// 私有构造方法
private SinglePattern() {
}
//用于对外提供实例
public static SinglePattern getInstance() {
if(single==null) {
synchronized (SinglePattern.class) {
if(single==null) {
single=new SinglePattern();
}
}
}
return single;
}
}
在这种方式下,进行了两次判断,可以保证线程安全,并且实例化代码只执行一次,效率高
四.单例模式的应用场景
1.计数器统计点击次数或者在线人数
2.多线程的线程池
3.读取配置文件
4.日志应用
之前看到一篇关于单例模式的介绍,总结的很好:https://www.cnblogs.com/zhaoyan001/p/6365064.html