7种单例模式

7种单例模式

单例模式
模式是脱离语言的。
问题的由来:为什么?
多个线程操作不同实例对象。多个线程要操作同一对象,要保证对象的唯一性
解决的问题:
实例化过程中只实例化一次
解决的思路
有一个实例化的过程(只有一次),产生实例化对象 new
提供返回实例对象的方法:getInstace()
单例模式的分类
线程的安全性、性能、懒加载(lazy )
1) 饿汉式

public class HungerySingleton {
    //加载的时候就产生的实例对象
    private static HungerySingleton instance=new HungerySingleton();
    private HungerySingleton(){
    }


    //返回实例对象
   public static HungerySingleton getInstance(){
        return instance;
   }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                System.out.println(HungerySingleton.getInstance());
            }).start();
        }
    }
}

线程安全性:在加载的时候已经被实例化,所以只有这一次,线程安全的。JVM ClassLoader
懒加载:没有延迟加载,好长时间不使用,影响性能,长时间置于内存也存在安全问题
性能比较好

2),懒汉式(懒加载)

public class HoonSingleton {
    private static HoonSingleton instance=null;
    private HoonSingleton(){
    }
    public static HoonSingleton getInstance(){
        if(null==instance)
            instance=new HoonSingleton();
        return instance;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                System.out.println(HoonSingleton.getInstance());
            }).start();
        }
    }
}

线程安全:不能保证实例对象的唯一性,因此不安全
懒加载:实现了懒加载
性能好

3)懒汉式+同步方法
线程安全:不能报证产生单个实例,可能产生多个实例。
懒加载
性能:synchronized退化到了串行执行,因此性能不好

public class DCL {
    private static DCL instance=null;
    private DCL(){
    }
    public  static DCL getInstance(){
        if(null==instance) {
synchronized (DCL.class){
               instance=new DCL();
            }
}


        return instance;
    }


    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                System.out.println(DCL.getInstance());
            }).start();
        }
    }
}

4)Double-Check-Locking

public class DCL {
    private static DCL instance=null;
    private DCL(){
    }
    public  static DCL getInstance(){
        if(null==instance)
            synchronized (DCL.class){
               if(null==instance)
                    instance=new DCL();
            }
        return instance;
    }
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                System.out.println(DCL.getInstance());
            }).start();
        }
    }
}

性能比较好
懒加载
线程的安全性:只会产生一个实例
问题:因为指令重排可能会引起空指针异常

5)Volatile+Double-check

private volatile static DCL instance = null;

6)Holder
声明类的时候,成员变量中不声明实例变量,而放到内部静态类中,

public class HolderDemo {
    private HolderDemo(){
    }
    private static class Holder{
        private static HolderDemo instance=new HolderDemo();
    }
    //懒加载
    public static HolderDemo getInstance(){
        return Holder.instance;
}
    //广泛的一种单例模式
}

性能比较好,没有使用加锁
懒加载
线程的安全性:只会产生一个实例

7)枚举
Effectice Java

public class EnumSingletonDemo {
    private EnumSingletonDemo(){
    }
    //延迟加载
    private enum EnumHolder{
        INSTANCE;
        private static EnumSingletonDemo instance=null;
        private EnumSingletonDemo getInstance(){
            instance=new EnumSingletonDemo();
            return instance;
        }
}
//懒加载
    public static EnumSingletonDemo getInstance(){
        return EnumHolder.INSTANCE.instance;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值