单例模式

单例模式是设计模式中最简单,最常用的一种。
六种实现均是线程安全的,我们根据是否懒加载?

  1. 是。懒汉式(同步方法),双重校验锁,静态内部类、枚举单例
  2. 否。饿汉式,静态代码块 在一般情况下,我们使用饿汉式(静态代码块)就可以的,在类的装载时就生成好对象,比如日常的各种池,数据库连接池,线程池等等,都是项目启动就初始化好该单例对象。
    如果实在是要达到懒加载的目的,说的好处是:避免类装载时加载对象,浪费内存。
    关于懒加载并且要求线程安全,这四种方式都可以的。
    但是不推荐同步方法的懒汉式,多线程时存在锁等待,而除了第一次生成对象,需要锁来保证只生成一个对象,后续多次使用都不用这个锁了,直接返回静态变量即可。
    后三种方式,都是比较好的。
    学习时,双重校验锁,除了在学习第二次if判断时,关于多线程同步的考虑,还需要注意jvm的指令序列的重排序导致的错误,这也是静态变量使用到volatile的原因,具体的可以看看这本书《Java并发编程的艺术》的相关章节。
    而静态内部类方法,需要我们学习内部类的相关知识,以及类加载的相关知识。具体的可以看看这本书《Java并发编程的艺术》的相关章节。
    枚举单例方法,是枚举的相关实现,这个需要我们理解枚举原理相关知识,推荐博客一篇

以下是实现代码:

/*饿汉式*/
public class Singleton{
    private final static Singleton INSTANCE = new Singleton();

    private Singleton(){}

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

/*静态代码块*/
public class Singleton{
    private static Singleton instance;

    static{
        instance = new Singleton();
    }

    private Singleton(){}

    public static Singleton getInstance(){
        return instance;
    }

}

/*懒汉式,同步方法*/
public class Singleton{
    private static Singleton singleton = null;

    private Singleton(){}

    public static synchronized Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }else{
            return singleton;
        }

    }

}

/*双重锁检验*/
public class Singleton{
    private static volatile Singleton singleton;

    private Singleton(){}

    public static Singleton getInstance(){
        if(singleton == null){
            synchronized(Singleton.class){
                if(singleton == null){
                    singleton = new Singleton();

                }
            }

        }
        return singleton;
    }
}

/*静态内部类*/
public class Singleton{
    private Singleton(){}

    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }


}

/*枚举*/
public enmu SingletonInstance{
    INSTANCE;

    private Singleton singleton = null;

    private SingletonInstance(){
        singleton = new Singleton();
    }

    public Singleton getInstance(){
        return singleton;
    }
}
//使用:SingletonInstance.INSTANCE.getInstance();
文章目录
|