设计模式——单例模式

来源:互联网 发布:淘宝自动下架 编辑:程序博客网 时间:2024/06/06 01:25

欢迎转载,请附出处:
http://blog.csdn.net/as02446418/article/details/47952947

单例模式(Singleton)

首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了,

比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,

这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,

即在整个的打印过程中我只有一个打印程序的实例。

简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,

任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。

单例模式的结构图

这里写图片描述

从上面的类图中可以看出,在单例类中有一个构造函数 Singleton ,

但是这个构造函数却是私有的(前面是“ - ”符号),

然后在里面还公开了一个 GetInstance()方法,

通过上面的类图不难看出单例模式的特点,从而也可以给出单例模式的定义

单例模式保证一个类仅有一个实例,同时这个类还必须提供一个访问该类的全局访问点。

下面来看代码:

public class Singleton1 {    private static Singleton1 instance;    private Singleton1(){        System.out.println("我是线程不安全的饿汉singleton");    }    public static Singleton1 getSingleton1(){        if (instance==null) {            instance = new Singleton1();        }        return instance;    }}

如上面代码所示,这种写法是最不推荐的,也是因为它的线程不安全,我们来看一下测试代码和运行结果:

线程不安全的singleton

public class SingletonTest {    public static void main(String[] args){        for (int i = 0; i < 100; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    Singleton1.getSingleton1();                }            }).start();        }    }}

这里写图片描述

这里new了三个singleton,在多线程环境下可能存在多个线程判断instance==null,所以会分别new出自己的instance,这显然违背了单例模式的初衷。

接下来我们换种写法:

线程安全的饿汉singleton

public class Singleton2 {    private static Singleton2 instance = new Singleton2();    private Singleton2(){        System.out.println("我是线程安全的饿汉singleton");    }    public static Singleton2 getSingleton1(){        return instance;    }}

下面是运行结果:
这里写图片描述

为什么说是饿汉的singleton,因为如上面代码所示,在用到示例instance之前就已经把它初始化好了,虽然这里是线程安全的,但是也会影响性能,所以我们来看第三种singleton。

线程安全的懒汉singleton

public class Singleton {    private Singleton(){        System.out.println("我是线程安全的singleton");    }    private static class singletonHolder{        private final static Singleton instance = new Singleton();    }     public static Singleton getSingleton(){        return singletonHolder.instance;    }}

下面是运行结果:
这里写图片描述

如上述代码所示,这里用到了singletonHolder这个内部类,这个内部类只会在singletonHolder.instance中用到,也就是用的时候才会初始化,故称为懒汉singleton,这样既解决了多线程下不安全的问题,同时也解决了提前初始化影响的性能问题,所以是最推荐的一种写法。

0 0
原创粉丝点击