单例模式

来源:互联网 发布:公称壁厚的算法 编辑:程序博客网 时间:2024/05/16 06:34

Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。

单例设计模式分为两种:饿汉式和懒汉式

1,饿汉式

public class Single{private static final Single s = new Single();private Single(){ }public static Single getInstance(){return s ;}}

2,懒汉式

public class Single{private static Single s = null;private Single(){ }public static Single getInstance(){if(s==null){synchronized(Single.class){if(s==null){s = new Single();}}}return s ;}}


懒汉式会延迟对象的实例化和加载,但也会出现线程安全问题,所以需要使用对象锁,锁所绑定的是类的字节码文件对象。同时,使用锁会使效率降低,应使用双层判断的方法减少判断锁的次数。

要使用线程安全的延迟的单例初始化,我们还有一种方法,称为Initialization on demand holder  模式 。

package com.chapter3.singleton;public class LazyLoadedSingleton {private LazyLoadedSingleton(){} private static class LazyHolder {private static final LazyLoadedSingleton instance = new LazyLoadedSingleton();}public static LazyLoadedSingleton getInstance(){return LazyHolder.instance;}}

当JVM加载LazyLoadedSingleton类时,由于该类没有static 属性,所以加载完成后即可返回。只有第一次调用getInstance()方法时,JVM才会加载LazyHolder类,由于它包含一个static属性instance,所以首先初始化这个变量。


如果单例类实现了Serializable接口,由于每次反序列化(Deserialization)总会创建一个新的实例对象,为了保证系统始终只有一个对象供使用,我们需在readResolve()方法里做文章,此方法在反序列化完成之前执行,我们在此方法替换掉反序列化出来的那个新的实例,让其指向内存中的那个单例对象即可:

package com.chapter3.singleton;import java.io.Serializable;public class SerialibleSingleton implements Serializable {private static final long serialVersionUID = -1750805615520866202L;private final static  SerialibleSingleton instance = new SerialibleSingleton();private SerialibleSingleton(){}public static SerialibleSingleton getInstance() {        return instance;    }    // This method is called immediately after an object of this class is deserialized.    // This method returns the singleton instance.    private Object readResolve() {        return instance;    }}