设计模式复习--单例模式

单例模式,可以说是设计模式种最简单的模式了,因为它只有一个对象,这也就呼应了它的名字“单例模式”,至于为什么只有一个对象,下面会进一步讲述。

这里先说说单例模式的使用场景吧,在此我总结了以下几种:
1.数据共享。例如:线程池,需要管理线程的数量
2.提高效率,降低内存损耗。例如:DB连接池,连接的是同一种数据资源,所以频繁的打开关闭会造成效率损耗,而且会大量的产生对象,造成不必要的内存消耗
3.考虑线程安全。

下面给出一个例子来说明一下单例模式:这个例子很简单,也很贴近生活,那就是平时家里使用的自动蓄水器,每当水蓄满的时候就会停止蓄水:
上面的例子如果不使用单例模式来实现,就会发生当使用者多次按下蓄水操作按钮的时候,会导致实例化多个蓄水操作的对象,由于对象的成员变量属于对象私有的(静态的例外),所以不可以进行数据共享,也非线程安全,最终导致蓄水器在水蓄满了以后还会继续进行蓄水导致溢出。这是由于多的对象对同一事件进行操作的结果。
然而单例模式,不管使用者多次按下蓄水操作按钮,始终都是只有一个蓄水操作的对象,这样可以有效的进行数据共享,而且是线程安全,当水蓄满了以后,就会终止给水操作,有效的防止了溢出。

下面给出单例模式的实现方式:
第一种,最简单的就是人们说的“饿汉式”

public class SingleTop {

    private final static SingleTop st = new SingleTop();

    public final static SingleTop getInstance() {
        return st;
    }
    //这里就回答了上面为什么,单例模式只有一个对象的问题了
    //构造方法是有化,外面不可以调用构造方法
    private SingleTop() {
    }

}

这个方式它的优点就是确保了当前类只有一个对象,缺点是当大量存在这种模式的时候,有可能造成不必要的资源开销。
下面就进行改良延迟实例化,其中

public class SingleTop {

    private static SingleTop st;

    public final static SingleTop getInstance() {
        if (st == null)
            st = new SingleTop();
        return st;
    }

    private SingleTop() {
    }

}

这种方式在需要用到的时候才进行实力,可以解决了不必要的开销,但是在多线程上就难以确保,对象的唯一性了,当第一个线程还没实例化完成,第二个线程就进行 st == null,这种情况下就会有多个对象存在了
,所以这种情况比较适合用于单线程;
好了下面继续对他进行修改:

public class SingleTop {

    private static SingleTop st;

    public final synchronized static SingleTop getInstance() {
        if (st == null)
            st = new SingleTop();
        return st;
    }

    private SingleTop() {
    }

}

这种方式解决了,线程安全区别同时只有个线程调用,但是这种方式在高并发的程序中是相当糟糕的。
下面继续修改:

public class SingleTop {

    private static SingleTop st;

    public final static SingleTop getInstance() {
        if(st == null){
            synchronized (SingleTop.class) {
                if(st == null)
                    st = new SingleTop();
            }
        }
        return st;
    }

    private SingleTop() {
    }

}

通过双重检索的方式,既可以减低不必要的开销,又符号线程安全,还解决了并发的问题。这就比较完美的实现方法了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值