Java设计模式之单例模式

来源:互联网 发布:阿里云oss 图片 文件夹 编辑:程序博客网 时间:2024/05/24 01:40

  • 单例设计模式Singleton
    • 引言
    • 单例设计模式的实现
      • 懒汉式
      • 饿汉式
    • 总结

单例设计模式(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关键字可以保证线程安全,另外双重同步锁判断方式比同步方法效率更高。

0 0