单例设计模式
单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例。
- 定义:
- 私有化该类的构造函数
- 通过new在本类中创建一个本类对象
- 定义一个公有的方法,将在该类中所创建的对象返回
- 属于创建型模式
饿汉式
- 非懒加载
- 线程安全
- 实现简单
/**
* 饿汉式
* 优点: 实现简单,在类加载的时候就完成了实例化,避免了线程的同步问题,没有加锁,执行效率会提高。
* 缺点:类加载时就初始化,会造成内存的浪费。
*/
public class Singleton {
private Singleton() {
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
懒汉式
线程不安全
- 懒加载
- 线程不安全
- 实现简单
/**
* 线程不安全的懒汉式
*/
public class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
线程安全
- 懒加载
- 线程安全
- 实现简单
/**
* 线程安全的懒汉式
* 优点:首次调用才初始化,避免内存浪费
* 缺点:必须加锁才能保证单例,影响效率
*/
public class Singleton {
private Singleton() {
}
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
双重校验锁
- 懒加载
- 线程安全
/**
* 双重校验锁
*/
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
登记式/静态内部类
- 懒加载
- 线程安全
/**
* 登记式/静态内部类
* 利用了 classloader 机制来保证初始化 instance 时只有一个线程
* SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance
*/
public class Singleton {
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
枚举
- 非懒加载
- 线程安全
/**
* 枚举
* 这里的instance即为SingletonEnum类型的引用所以得到它就可以调用枚举中的方法了。
* 借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化
*/
public enum SingletonEnum {
instance;
private SingletonEnum(){}
public void whateverMethod(){
}
// 使用
// SingletonEnum.instance.whateverMethod();
}