Apricot

初识单例模式
1.什么是单例模式单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整...
扫描右侧二维码阅读全文
30
2019/06

初识单例模式

1.什么是单例模式

单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。
也就是说,在整个程序空间中,该类只存在一个实例对象。
其实,GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

2.为什么要使用单例模式

在应用系统开发中,我们常常有以下需求:

  • 在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象
  • 在整个程序空间使用全局变量,共享资源
  • 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。

*举个栗子

例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;售票时,一共有100张票,可有有多个窗口同时售票,但需要保证不要超售(这里的票数余量就是单例,售票涉及到多线程)。如果不是用机制对窗口对象进行唯一化将弹出多个窗口,如果这些窗口显示的都是相同的内容,重复创建就会浪费资源。

因为Singleton模式可以保证为一个类只生成唯一的实例
对象,所以这些情况,Singleton模式就派上用场了。

3.分类

(1).懒汉式 1 :(线程不安全)

public class SingletonDemo1 {
    private static SingletonDemo1 instance;
    private SingletonDemo1(){}
    public static SingletonDemo1 getInstance(){
        if (instance == null) {
            instance = new SingletonDemo1();
        }
        return instance;
    }
}

这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。

(2).懒汉式2 (线程安全)

public class SingletonDemo2 {
    private static SingletonDemo2 instance;
    private SingletonDemo2(){}
    public static synchronized SingletonDemo2 getInstance(){
        if (instance == null) {
            instance = new SingletonDemo2();
        }
        return instance;
    }
}

这种写法在getInstance()方法中加入了synchronized锁。能够在多线程中很好的工作,而且看起来它也具备很好的lazy loading,但是效率很低(因为锁),并且大多数情况下不需要同步。

(3) 饿汉式

public class SingletonDemo3 {
    private static SingletonDemo3 instance = new SingletonDemo3();
    private SingletonDemo3(){}
    public static SingletonDemo3 getInstance(){
        return instance;
    }
}

这种方式基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,这时候初始化instance显然没有达到lazy loading的效果。

(4)饿汉式(变种)

public class SingletonDemo4 {
    private static SingletonDemo4 instance = null;
    static{
        instance = new SingletonDemo4();
    }
    private SingletonDemo4(){}
    public static SingletonDemo4 getInstance(){
        return instance;
    }
}

(5)枚举

public enum SingletonDemo5{
    instance;
    public void fun(){
    }
}

(6)双层检查

public class SingletonDemo7 {
    private volatile static SingletonDemo7 singletonDemo7;
    private SingletonDemo7(){}
    public static SingletonDemo7 getSingletonDemo7(){
        if (singletonDemo7 == null) {   //判断对象是否被创建
            synchronized (SingletonDemo7.class) {  
                if (singletonDemo7 == null) {   //在并发是判断对象是否被创建
                    singletonDemo7 = new SingletonDemo7();
                }
            }
        }
        return singletonDemo7;
    }
}

参考:http://cantellow.iteye.com/blog/838473

最后修改:2019 年 06 月 30 日 03 : 16 AM
你们随意,我干了哈

发表评论