Java 单例模式常见五种实现方式

定义

单例模式,属于创建类型的一种常用的软件设计模式。
单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”
Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”

饿汉式 与 懒汉式

饿汉式:类装载的时候就完成实例化。避免了线程同步问题。可能造成内存浪费。
懒汉式:延迟加载,只有在用到的时候才进行实例化。存在线程不安全问题。

单例模式实现要点

  1. 创建静态属性存放实例
  2. 构造方法私有化,使外部无法new创建实例对象
  3. 提供公有静态方法获取实例对象

单例模式的五种实现方式

单例模式常见五种实现:饿汉式、枚举饿汉式、懒汉式、双检锁懒汉式、内部类懒汉式。

1、饿汉式(可用)

/**
 * @author chenxp
 * 1. 饿汉式单例
 */
public class Singleton1 {

    private static final Singleton1 INSTANCE = new Singleton1();

    private Singleton1(){
    }

    public static Singleton1 getInstance() {
        return INSTANCE;
    }
}

2、枚举饿汉式(推荐)

/**
 * @author chenxp
 * 2. 枚举饿汉式单例
 */
public enum Singleton2 {
    INSTANCE;

	// 可省略
    private Singleton2() {
    }
    
    // 可省略
    public static Singleton2 getInstance() {
        return INSTANCE;
    }
}

3、懒汉式(不推荐)

/**
 * @author chenxp
 * 3. 懒汉式单例
 */
public class SingleTon3 {

    private static SingleTon3 INSTANCE = null;

    private SingleTon3() {
    }

    public static synchronized SingleTon3 getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new SingleTon3();
        }
        return INSTANCE;
    }
}

4、双检锁懒汉式(推荐)

/**
 * @author chenxp
 * 4. 双检锁-懒汉式单例
 */
public class Singleton4 {
    /**
     * volatile 保证可见性、有序性,防止指令重排序
     */
    private static volatile Singleton4 INSTANCE = null;

    private Singleton4() {
    }

    public static Singleton4 getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton4.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton4();
                }
            }
        }
        return INSTANCE;
    }
}

5、内部类懒汉式(推荐)

/**
 * @author chenxp
 * 5. 内部类懒汉式单例
 */
public class Singleton5 {

    private Singleton5() {
    }

    private static class Holder {
        static Singleton5 INSTANCE = new Singleton5();
    }

    public static Singleton5 getInstance() {
        return Holder.INSTANCE;
    }
}

使用场景

  1. 需要频繁的进行创建和销毁的对象;
  2. 创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象;
  3. 工具类对象;
  4. 频繁访问数据库或文件的对象(比如数据源、session工厂等)。

扩展

可能破坏单例三种方式:
①反射破坏单例
②反序列破坏单例
③Unsafe 破坏单例

你可能感兴趣的:(面试准备,单例模式,java,面试)