Java设计模式之单例模式

来源:互联网 发布:淘宝客服兼职 招聘找 编辑:程序博客网 时间:2024/06/05 15:35

今天总结一下java设计模式中的单利模式。所谓单例模式就是一个类只能有一个实例化对象,并且提供一个全局的访问点。为什么需要单例模式?可能我们会想,一个类怎么会只有一个实例,其实这种需求还是挺多的,比如:线程池、缓存、对话框、注册表的对象以及显卡等驱动设备的对象。这些对象一般只能存在一个,如果存在多个这样的对象就会出现一些问题,比如同时出现两个显卡对象,那么这两个显卡都会控制到你电脑,那么就有可能产生冲突,这肯定是不行的。

单例模式的实现原理是什么?通常我们实例化一个对象是通过new操作符,比如new Singleton.但这样,可以有多个对象进行new Singleton().这样就会产生多个类的实例。我们知道类的初始化操作是在构造器中进行的,而构造器是可以被访问的,如果我们将构造器设置为private的会怎么样呢? 也就是我们不允许其他对象去访问这个构造器,也就无法通过new Singleton()来实例化这个类。那么就只能通过在类的内部去调用这个构造方法,于是我们可以想到,在类内部定义一个方法getInstance(),我们通过返回一个类的实例即通过return new Singleton()语句可以得到这个类的实例,但是因为我们在类外无法创建一个对象,所以也就无法去调用这个方法呢,怎么办?这个时候我们可以将这个方法设置为静态的,这样我们可以在外部通过类去直接调用这个方法(Singleton.getInstance())。还有一个问题,这样做,也不能保证这个类只有一个实例,我们如果通过类去多次调用这个方法,不也会产生多个实例。这个时候,我们可以在类的内部增加一个类的静态成员变量(static Singleton uniquenceInstance),在实例化的方法getInstance()中去判断这个值是否为null,如果为null,则去实例化这个对象,如果不为null则直接返回这个静态成员变量。下面就看具体的代码:

public class Singleton {private static Singleton uniquenceInstance ;//私有构造方法 private Singleton() {//初始化操作}public static Singleton getInstance() {if(uniquenceInstance==null) {uniquenceInstance = new Singleton();}return uniquenceInstance;}}
上面这段代码,是经典的单例模式实现。不过这个单例模式在有些情况下还是会有问题,比如多个线程可能会异步的执行了上述代码,那么是有可能创建出多个实例的。这样肯定是不行,我们可以想到,在多线程中有个同步方法,所以我们将实例化方法,改为同步方法即可。

public class Singleton {private static Singleton uniquenceInstance ;//私有构造方法 private Singleton() {//初始化操作}          //改为同步方法private static <span style="color:#FF0000;">synchronized </span>Singleton getInstance() {if(uniquenceInstance==null) {uniquenceInstance = new Singleton();}return uniquenceInstance;}}

这样做就可以解决多线程的问题,不过这样做是有代价的,会使性能大大降低。因为我们每一次执行getInstance()方法,都会进行一次同步,但我们只需要第一次执行此方法的时候需要同步,即当uniquenceInstance变量已经设置好的时候,我们是不需要同步的。我们可以采用“急切”创建实例的方式,来实例化类,而前面的方式是延迟实例化的方法。我们看一下代码实现:

public class Singleton {private static Singleton uniquenceInstance = new Singleton();        private Singleton() {}        public static Singleton getInstance() {return uniquenceInstance;}}
这样,我们就可以利用JVM在加载这个类的时候马上去创建唯一的类的实例,JVM确保在任何线程访问uniquenceInstance静态变量之前,一定先创建此实例。

至于我们是需要”急切实例化方式“还是”延迟实例化方式“可以根据自己的实际开发需要来进行选择。这次单例模式就说这么多,多加实践才能体会到它的优缺点, do it!

1 0
原创粉丝点击