设计模式之单例模式

  单例模式是一种比较常用的设计模式,提供了对唯一实例的受控访问,由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。

  但是,由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出。

  如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。(以上是借鉴大神的话,大神说的话总是不可挑剔,嘿嘿)

  之前虽然有用过单例模式,但是都没有深入去了解过,直到在一本讲高并发的书上看到,就对单例模式感兴趣起来,现在就来谈谈单例模式吧!

网上搜了很多单例模式的博客,有着各种各样的说法,而我最常用的单例模式是这种(听说这叫双重检查锁定单例模式,又叫懒汉单例模式。好奇怪的名字!):

这种模式第一次使用才初始化,避免浪费内存,但必须加锁才能完成单例,执行效率低

class Person {

    private static Person instance;

    private Person(){}

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

而在高并发这本书中我了解到懒汉单例模式写法的线程安全与高并发的一些知识:

第一种:线程不安全

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

第二种:线程安全,但是高并发性能不高

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

第三种:线程安全,性能高,而且最常见的,和上面说的我比较常用的相似,但比我的那个效率高,因为这个加锁的对象是字节对象,占内存低,执行效率会高一丢丢

class Person {
    private static Person instance;
    private static byte[] lock = new byte[0];
    private Person(){}
    public static Person getInstance(){
        if(instance == null){
            synchronized (lock){
                if(instance == null){
                    instance = new Person();
                    }
                }
        }
        return instance;
    }
}

第四种:线程安全,性能高,我想这个只有经常用多线程的人才会写这个(反正我很少写,这是第二次!)

class Person {
    private static Person instance;
    private static ReentrantLock lock = new ReentrantLock();
    private Person(){}
    public static Person getInstance(){
        if(instance == null){
            lock.lock();
            if(instance == null){
                instance = new Person();
            }
            lock.unlock();
        }
    return instance;
    }
}

既然有懒汉单例模式,会不会还有其他的单例模式呢?答案是肯定的,让我们了解另外一种单例模式–饿汉单例模式:

这种单例模式因为没有加锁,执行效率会高,但是类加载时就初始化,很耗内存。

class Person{
    private static final Person PERSON = new Person();
    private Person(){}
    public static Person getIntance(){
        return PERSON;
    }
}

还有一种单例模式叫登记单例模式

听说这是最好的单例模式,解决了上面单例模式的缺点(不知道是不是,再查查,嘿嘿)

public Person{
    private Person(){}
    private static Person getInstance(){
        return Hodler.PERSON;
    }
    private static class Hodler{
        private static final Person PERSON = new Person();
    }
}

注意:

  • 单例模式需要私有化构造函数
  • 定义静态的Singleton instance对象和getInstance()方法
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值