单列模式

13年前
  • 什么是单列模式      
单例模式就是某个类只存在一个对象(只new 一次),当某个类的初始化比较耗时,耗资源的时候,比如加载某些配置文件hibernate,spring的配置文件等,一般会选择单例模式。
当某个类的初始化比较耗时,耗资源的时候一般会选择单例模式。 
  • 单列模式的应用
单例模式一般用在你不想实例化多个对象的地方,通常这类对象比较耗资源,还有加载默写配置文件的时候,因为只需加载一次就可,链接数据库时也可用单例模式,synchronized是java只是里的一个关键字,和单例是两个概念,它用来保证同一个对象不被多个线程共同调用,因为多个线程同时调用一个对象会用问题,synchronized用在单例里面的意思是这个单例只会被一个线程调用,在多个线程内还是一个 

 

  • 单列模式举例
单例模式是一种常见的设计模式,在《Java与模式》一书中,阎宏博士对单例模式做了全面的总结。  单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。  单例模式有一下特点:  1、单例类只能有一个实例。  2、单例类必须自己自己创建自己的唯一实例。  3、单例类必须给所有其他对象提供这一实例。  说明:一下的代码来自阎宏博士的《Java与模式》一书,其中对一些类的写法做调整(符合Java1.5的习惯),另外还加了测试方法。   一、懒汉式单例  在类被加载的时候,唯一实例已经被创建。这个设计模式在Java中容易实现,在别的语言中难以实现。  /**  * Created by IntelliJ IDEA.  * User: leizhimin  * Date: 2007-9-11  * Time: 14:57:08  * <<Java与模式>> 单例模式-懒汉式单例  */  public class LazySingleton {       /**        * 私有静态对象,加载时候不做初始化        */       private static LazySingleton m_intance=null;       /**        * 私有构造方法,避免外部创建实例        */       private LazySingleton(){       }       /**        * 静态工厂方法,返回此类的唯一实例.          * 当发现实例没有初始化的时候,才初始化.        * @return LazySingleton        */       synchronized public static LazySingleton getInstance(){           if(m_intance==null){               m_intance=new LazySingleton();           }           return m_intance;       }  }  二、饿汉式单例  在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。  /**  * Created by IntelliJ IDEA.  * User: leizhimin  * Date: 2007-9-11  * Time: 14:45:25  * <<Java与模式>> 单例模式-饿汉式单例  */  public class EagerSingleton {       /**        * 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象        */       private static final EagerSingleton m_instance = new EagerSingleton();       /**        * 私有构造方法,避免外部创建实例        */       private EagerSingleton() {       }       /**        * 静态工厂方法,返回此类的唯一实例.        * @return EagerSingleton        */       public static EagerSingleton getInstance() {           return m_instance;       }  }  三、登记式单例  这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。  /**  * Created by IntelliJ IDEA.  * User: leizhimin  * Date: 2005-9-11  * Time: 15:20:16  * <<Java与模式>> 单例模式- 登记式单例  */  public class RegSingleton {       /**        * 登记薄,用来存放所有登记的实例        */       private static Map<String, RegSingleton> m_registry = new HashMap();       //在类加载的时候添加一个实例到登记薄       static {           RegSingleton x = new RegSingleton();           m_registry.put(x.getClass().getName(), x);       }       /**        * 受保护的默认构造方法        */       protected RegSingleton() {       }       /**        * 静态工厂方法,返回指定登记对象的唯一实例;        * 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回        * @param name        * @return RegSingleton        */       public static RegSingleton getInstance(String name) {           if (name == null) {               name = "RegSingleton";           }           if (m_registry.get(name) == null) {               try {                   m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());               } catch (InstantiationException e) {                   e.printStackTrace();               } catch (IllegalAccessException e) {                   e.printStackTrace();               } catch (ClassNotFoundException e) {                   e.printStackTrace();               }           }           return m_registry.get(name);       }       /**        * 一个示意性的商业方法        * @return String        */       public String about() {           return "Hello,I am RegSingleton!";       }  }  四、单例模式的一个应用  该应用是配置文件管理类。为了本例能正确运行,我在C盘下先建立了一个xxxx.properties文件,内容如下:  -------------------  user=root  password=leizhimin  这个配置文件管理类的代码如下:  /**  * Created by IntelliJ IDEA.  * User: leizhimin  * Date: 2005-9-11  * Time: 15:55:01  * 单例模式应用-单例类应用-配置文件管理  */  public class ConfigManager {       /**        * 属性文件全名        */       private static final String PFILE = "C:\\xxx.properties";       /**        * 对应于属性文件的文件对象变量        */       private File m_file = null;       /**        * 属性文件的最后修改日期        */       private long m_lastModifiedTime = 0;       /**        * 属性文件所对应的属性对象变量        */       private Properties m_props = null;       /**        * 本类可能存在的唯一的一个实例        */       private static ConfigManager m_instance = new ConfigManager();       /**        * 私有构造子,用以保证外界无法直接实例化        */       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 (IOException e) {               e.printStackTrace();           }       }       /**        * 静态工厂方法        *        * @return ConfigManager        */       synchronized public static ConfigManager getInstance() {           return m_instance;       }       /**        * 获取属性配置项的值        *        * @param name        * @param defaultVal        * @return Object        */       public final Object getConfigItem(String name, Object defaultVal) {           long newTime = m_file.lastModified();           if (newTime == 0) {               //属性文件不存在               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();               try {                   m_props.load(new FileInputStream(PFILE));               } catch (IOException e) {                   e.printStackTrace();               }           }           m_lastModifiedTime = newTime;           Object val = m_props.getProperty(name);           if (val == null) {               return defaultVal;           } else {               return val;           }       }  }  测试配置文件类:  /**  * Created by IntelliJ IDEA.  * User: leizhimin  * Date: 2007-9-11  * Time: 16:42:45  * 配置文件管理类测试  */  public class Test_ConfigManager {       public static void main(String[] args) {           ConfigManager cfgm = ConfigManager.getInstance();           Object val1 = cfgm.getConfigItem("sdf", "leizhimin");           Object val2 = cfgm.getConfigItem("user", "leizhimin");           System.out.println(val1.toString());           System.out.println(val2.toString());       }  }  运行结果:  leizhimin  root  Process finished with exit code 0