您的位置:首页 > 其它

设计模式——单例模式

2015-08-24 16:22 274 查看
欢迎转载,请附出处:

/article/1760828.html

单例模式(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,这样既解决了多线程下不安全的问题,同时也解决了提前初始化影响的性能问题,所以是最推荐的一种写法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: