读书人

singleton 方式初识

发布时间: 2012-10-08 19:54:56 作者: rapoo

singleton 模式初识
SINGLETON模式
一、引言
想学习关系线程安全方面的,引申到singleton模式,知道这个模式,还是想系统的先弄明白.
二、定义与结构
?单例类只有一个实例
?单例类必须自己创建自己的唯一的实例
?例类必须给所有其他对象提供这个唯一的实例
三、实现方式
引用java与模式中的三种实现方式。

第一种;饿汉式单例类
构造方法私有,避免外界利用构造方法随意的创建实例,因此这个类也不能被继承。单实例在类装载时初始化。

public class EagerSingleton {    private EagerSingleton() { }    public static EagerSingleton getInstance() {        return m_instance;    }    /** @label Creates */    private static final EagerSingleton m_instance = new EagerSingleton();}

第二种:懒汉式单例类
此构造方法也为私有,同样不能被继承。在类首次实例化时创建,需要处理好多个线程首次同时引用此类时的 访问限制问题。
public class LazySingleton{    private LazySingleton() { }    synchronized public static LazySingleton getInstance()    {    if (m_instance == null)    {        m_instance = new LazySingleton();    }    return m_instance;}    /**     * @label Creates      */    private static LazySingleton m_instance = null;}

第三种:登记式单例

import java.util.HashMap;public class RegSingleton {    protected RegSingleton() {}    static public RegSingleton getInstance(String name)    {        if (name == null)        {            name = "com.javapatterns.singleton.demos.RegSingleton";        }        System.out.println("From RegSingleton: requesting for " + name );        if (m_registry.get(name) == null)        {            try            {                m_registry.put( name, Class.forName(name).newInstance() ) ;            }            catch(ClassNotFoundException e)            {                System.out.println("Class " + name + " is not found.");            }            catch(InstantiationException e)            {                System.out.println("Class " + name + " can not be instantiated.");            }            catch(IllegalAccessException e)            {                System.out.println("Class " + name + " can not be accessed.");            }        }        return  (RegSingleton) (m_registry.get(name) );    }    static private HashMap m_registry = new HashMap();    /**     * @label Creates     * @directed*/    /*# private RegSingletonChild lnkRegSingletonChild; */    /**     * @label Creates     * @directed     */    /*# private RegSingleton lnkRegSingleton;  */    static    {        RegSingleton x = new RegSingleton();        m_registry.put( x.getClass().getName() , x);    }    public String about()    {        return "Hello, I am RegSingleton.";    }}

由于构造方法非私有,子类可以继承,继承必须通过getInstance方法传入子类的类名。
import java.util.HashMap;public class RegSingletonChild extends RegSingleton{    public RegSingletonChild() {}    static public RegSingletonChild getInstance()    {        return (RegSingletonChild) RegSingleton.getInstance( "com.javapatterns.singleton.demos.RegSingletonChild" );    }    public String about()    {        return "Hello, I am RegSingletonChild.";    }}

缺点是在子类产生的实例可以不在父类中登记,其次是子类的实例的产生必须是父类的实例存在才能产生


四、实例
如上
属性管理器
import java.util.Properties;import java.io.FileInputStream;import java.io.File;/*** Only once instance of the class may be created during the* execution of any given program. Instances of this class should* be aquired through the getInstance() method. Notice that there* are no public constructors for this class.*/public class ConfigManager{   /*** The private constructor (enforces single instance)*/private ConfigManager(){m_file = new File(PFILE);m_lastModifiedTime = m_file.lastModified();if(m_lastModifiedTime == 0){            System.err.println(PFILE + " file does not exist!");        }m_props = new Properties();try{m_props.load(new FileInputStream(PFILE));}catch(Exception e){e.printStackTrace();}}/*** Returns the singleton ConfigManager** @return The one and only instance of the ConfigManager*/synchronized public static ConfigManager getInstance(){return m_instance;}/*** Gets a configuration item** @param name The name of the item* @param defaultVal The default value if name is not found* @return The value for the specified name*/final public Object getConfigItem(String name, Object defaultVal){long newTime = m_file.lastModified();// Check to see if configuration file has been modified// since the previous request. If so, then read in the new// contentsif(newTime == 0){// The props file was deleted or does not exist (!!)if(m_lastModifiedTime == 0)            {System.err.println(PFILE + " file does not exist!");            }else            {System.err.println(PFILE + " file was deleted!!");            }return defaultVal;}else if(newTime > m_lastModifiedTime){m_props.clear();// Get rid of the old propertiestry{m_props.load(new FileInputStream(PFILE));}catch(Exception e){e.printStackTrace();}}m_lastModifiedTime = newTime;Object val = m_props.getProperty(name);if( val == null )        {return defaultVal;        }else        {return val;        }}/*** The fully qualified name of the properties file*/private static final String PFILE = System.getProperty("user.dir") +  "/Singleton.properties";/*** The File object corresponding to the file that contains the properties*/private File m_file = null;/*** The last modified time of the properties file*/private long m_lastModifiedTime = 0;/*** The cached properties*/private Properties m_props = null;/*** The only instance of this class* @label Creates*/private static ConfigManager m_instance = new ConfigManager();


五、总结

读书人网 >软件架构设计

热点推荐