0
点赞
收藏
分享

微信扫一扫

单例模式的五种写法和优缺点

zhoulujun 2022-03-14 阅读 100

一、饿汉式
描述
顾名思义,急着用,也就是类加载的时候就实例化对象了。
实现

public class HungrySingleton {
    /**
     * 类加载的时候就实例化对象
     */
    private static HungrySingleton singleton = new HungrySingleton();
    /**
     * 私有构造方法
     */
    private HungrySingleton(){
 
    }
    /**
     * 返回实例对象的方法
     * @return
     */
    public static HungrySingleton getSingleton(){
        return singleton;
    }
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                HungrySingleton singleton = HungrySingleton.getSingleton();
                System.out.println(singleton);
            }).start();
        }
    }
}


优缺点
1.在类加载的时候就实例化对象,所以只实例化一次,保证了线程安全,性能比较好

2.没有实现延迟加载,长时间不适用的话,会占用内存,影响性能

二、懒汉式 
描述
不着急使用,也就是需要用的时候再去实例化对象
实现

public class HoonSingleton {
 
    private static HoonSingleton singleton = null;
 
    private HoonSingleton(){
 
    }
 
    /**
     * 使用的时候再实例化对象
     * @return
     */
    public static HoonSingleton getSingleton(){
        if (null == singleton) {
            singleton = new HoonSingleton();
        }
        return singleton;
    }
 
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                System.out.println(HoonSingleton.getSingleton());
            }).start();
        }
    }
}

优缺点
实现了懒加载、性能良好,但是不能保证实例化对象的唯一性,所以线程不安全
三、双重校验(DCL模式)
描述
实际上就是实例化之前进行两次对象的非空校验
实现

public class DCL {
 
    private  volatile static DCL singleton = null;
    private DCL(){
 
    }
 
    /**
     * 核心代码
     * @return
     */
    public  static DCL getSingleton(){
        if (null == singleton) {
            synchronized(DCL.class) {
                if (null == singleton) {
                    singleton = new DCL();
                }
            }
        }
        return singleton;
    }
 
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                System.out.println(DCL.getSingleton());
            }).start();
        }
    }
}


优缺点 
性能比较好,实现了懒加载,保证了线程安全。但是可能存在因指令重排引起空指针异常,
针对因指令重排序导致的空指针异常是可以使用volatile关键字解决。

四、静态内部类
 描述
Holder模式实际上就是使用内部类的方式实现单例模式(有点类似结合饿汉模式和懒汉模式)
实现

public class HolderDemo {
 
    /**
     * 内部类
     */
    private static class Holder {
        private static HolderDemo singleton = new HolderDemo();
    }
 
    public static HolderDemo getInstance(){
        return Holder.singleton;
    }
 
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                System.out.println(HolderDemo.getInstance());
            }).start();
        }
    }
 
}

优缺点
使用的时候才去实例化,实现了懒加载,性能好
在内部类中声明的实例对象,只实例化一次,保证了线程安全
 五、枚举实现(感觉用的比较少)
描述
实现

public class EnumSingletonDemo {undefined

    private EnumSingletonDemo(){undefined

    }

    //延迟加载

    private enum EnumHolder{undefined

        INSTANCE;

        private static  EnumSingletonDemo instance=null;



        private EnumSingletonDemo getInstance(){undefined

            instance=new EnumSingletonDemo();

            return instance;

        }

    }//懒加载

    public static EnumSingletonDemo  getInstance(){undefined

        return EnumHolder.INSTANCE.instance;

    }

}

优缺点
延迟加载、线程安全
以上就是单例模式的几种实现方式,不对之处还望指正。 

举报

相关推荐

0 条评论