Java设计模式之单例模式

单例设计模式(Singleton)

Java设计模式整理第一剑

在我的工作与学习中,对于Java的设计模式还处于只了解部分的阶段,只会简单的写出来,对于为什么要这样设计,这样设计有什么好处和缺点,还谈不上掌握,所以我决定抽出时间,系统性的整理学习,记下自己的学习心得,每天进步一小步。

引言

都说在Java程序员的眼里,世间万物皆对象,从面向对象的角度来看:

  • 我们的家里,是不是绝大多数只有一个卫生间呢,因为一个就可以满足我们的日常需求,不需要额外的占用更多的使用面积。
  • 当我们在买票的时候,一张票能不能同时被2个人买到使用呢?显然这样不合理,所以对于需要保证每张票唯一的特性,可能涉及到多个人同时操作的情况下,要保证这个对象的唯一性。
  • 在天朝,同一时间你最多只能娶一个老婆。。。好吧,这个是开玩笑。。。

通过上面的两个情景,我们可以总结一下单例模式的使用场景以及好处:

  • 一个对象只需要一个就可以满足我们的需求的时候,可以使用单例设计模式,它避免了创建其他实例所占用的资源开销。

  • 对于需要保证一个对象实例的唯一性的时候,我们需要采用单例设计模式。

单例设计模式的实现

通过上面的例子,我们简单地理解了单例设计模式的使用场景与好处,下面我们就在Java中,学习一下单例模式的使用方法。

懒汉式

懒汉式顾名思义,就是比较懒惰,上来的时候没有创建这个类的实例,而是当外部调用这个方法的时候,才会进行判断,如果为空,则创建该类的实例,并返回,不为空的时候,说明已经创建过了,直接返回该实例。

public class Darling {
    private Darling() {
        super();
    }
    private static Darling darling = null;

    public static Darling getInstance(){
        if (null == darling ) {
            darling = new Darling();
        }
        return darling;     
    }

}   

缺点:上面这种写法,并不是线程安全的。为了保证线程安全,我们可以通过下面的写法来保证。

  • 通过synchronized关键字来同步方法
public class Darling {
    private Darling() {
        super();
    }
    private static Darling darling = null;

    public static synchronized Darling getInstance(){
        if (null == darling ) {
            darling = new Darling();
        }
        return darling;     
    }

}

  • 双重锁判断
public class Darling {
    private Darling() {
        super();
    }

    private static Darling darling = null;

    public static Darling getInstance() {

        if (null == darling) {
            synchronized (Darling.class) {
                if (null == darling) {
                    darling = new Darling();
                }
            }
        }
        return darling;
    }

}


通过这种形式也保证了线程安全,而且相比上面的写法,这种效率更高,具体体现在:

  • 通过同步方法的方式,每次执行这个方法的时候,都需要进行同步。
  • 通过双重锁判断,当第一次判断为null的时候,A进入同步代码块内部的同时,进行同步锁,此时即使还未创建完成,B也执行了这个方法,但是因为有锁的存在,B进不来同步代码块,而当A创建完成之后此时darling已经不为null了,B进入了同步代码块里也不会再次创建,保证了线程安全,而且后续再次调用这个方法也不用再次进行同步,效率更高。

饿汉式

之所以成为饿汉式,可以理解为这个人已经饥渴难耐,饥不择食,迫不及待的上来就已经创建好了这个类的实例,而这个类的构造方法是私有的,外部无法通过new关键字来创建,只能通过我们定义的静态的方法拿到Darling对象,同时通过final关键字修饰,保证了它的唯一性,因此通过饿汉式的方法来创建,是线程安全的。


public class Darling {

    private Darling() {

    }

    private static final Darling darling = new Darling();

    public static Darling getInstance(){

        return darling;
    }

}


总结

饿汉式:

是天生线程安全的

懒汉式:

原本不是线程安全的,但是通过synchronized关键字可以保证线程安全,另外双重同步锁判断方式比同步方法效率更高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值