单例模式

2017-01-20  本文已影响0人  我的头好疼

单例模式

定义

单例模式是一个简单的模式,定义如下:
Ensure a class has only one instance ,and provide a global point of access to it.==(确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例)==
下面是单例模式的通用类图:

image

类图代码实现:

public class Singleton {
    private static final Singleton singleton = new Singleton();

    // 限制产生多个对象
    private  Singleton(){}

    // 通过该方法获得实例对象
    public static Singleton getSingleton() {
        return singleton;
    }
    
    // 类中的其他方法,尽量是static
    public static void dosomething(){}
}

public class Client {

    public static void main(String args[]){
        // 不能直接通过新建一个对象的方式来创建类的实例,只可以通过类的自身的方式创建对象
        Singleton singleton = Singleton.getSingleton();
        System.out.println(singleton.hashCode());
    }
}

分析

上面的单例模式的通用代码描述了单列模式的实现方式。Singleton称为单列类,通过使用private的构造函数确保了在一个应用中只产生一个实例,并且是自实例化的。

单例模式的应用

优点

缺点

单例模式的应用场景

在一个系统中,要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式,具体的场景如下:

单例模式的加载方式

懒汉模式

public class HungrySingleton {

    private static HungrySingleton singleton = null;

    private HungrySingleton(){}

    public synchronized static HungrySingleton getSingleton(){
        if(singleton == null){
            singleton = new HungrySingleton();
        }

        return singleton;
    }
}

该单例模式在低并发的情况下尚不会出现问题,若系统压力增大,并发量增加时则可能在内存中出现多个实例,破坏了最初的预期,举例:如一个线程A执行到singleton=new Singleton(),但还没有获得对象(对象初始化是需要时间的),第二个线程B也在执行,执行到(singleton==null)判断,那么线程B获得判断条件也是为真,于是继续运行下去,线程A获得了一个对象,线程B也获得了一个对象,在内存中就出现两个对象!
解决线程不安全的方法很有多,++可以在getSingleton方法前加synchronized关键字++,==也可以在getSingleton方法内增加synchronized来实现==,但都不是最优秀的单例模式,建议使用饿汉式单例,增加了synchronized的单例称为懒汉式单例)。

饿汉模式

public class Singleton {
    private static final Singleton singleton = new Singleton();

    private  Singleton(){}

    public static Singleton getSingleton() {
        return singleton;
    }
}

总结

i.由容器管理单例的生命周期

Java EE容器或者框架级容器(如Spring)可以让对象长久驻留内存。当然,自行通过管理对象的生命期也是一个可行的办法,既然有那么多的工具提供给我们,为什么不用呢?

ii. 状态随时记录

可以使用异步记录的方式,或者使用观察者模式,记录状态的变化,写入文件或写入数据库中,确保即使单例对象重新初始化也可以从资源环境获得销毁前的数据,避免应用数据丢失。

上一篇 下一篇

猜你喜欢

热点阅读