`

单例模式

 
阅读更多

java 单例模式的好处 

单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。


单例模式有一下特点:


1、单例类只能有一个实例。


2、单例类必须自己创建自己的唯一实例。


3、单例类必须给所有其他对象提供这一实例。


说明:一下的代码来自阎宏博士的《Java与模式》一书,其中对一些类的写法做调整(符合Java1.5的习惯),另外还加了测试方法。


一、懒汉式单例


在类被加载的时候,唯一实例已经被创建。这个设计模式在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;

     }

}


二、饿汉式单例


在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。

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(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。


public class RegSingleton {
 
     private static Map 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);

     }

     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


五、笔者写的一个JDBC数据库工具类的单例实现


/**


* Created by IntelliJ IDEA.


* User: leizhimin


* Date: 2005-9-11


* Time: 18:04:46


* 单例模式在JDBC编程中的应用,用于设计数据库工具类


*/


public class DBUtil {


     //单一实例

     private static final DBUtil _instance = new DBUtil();

     //数据源的JNDI

     private static final String datasource = "java:comp/env/jdbc/zvfims";

     /**

      * 私有构造方法,防止外部实例化

      */

     private DBUtil() {

     }

     /**

      * 数据库工具类实例工厂

      *

      * @return DBUtil

      */

     public DBUtil getInstance() {

         return _instance;

     }

     /**

      * 业务方法:用于获取数据库连接

      *

      * @return Connection

      */

     public Connection makeConnection() {

         Connection conn = null;

         try {

             Context ctx = new InitialContext();

             DataSource ds = (DataSource) ctx.lookup(datasource);

             conn = ds.getConnection();

         } catch (NamingException e) {

             System.out.println("获取数据源异常,请AppServer的JNDI数据源配置!");

             e.printStackTrace();

         } catch (SQLException e) {

             System.err.println("获取数据库连接发生异常!");

             e.printStackTrace();

         }

         return conn;

     }

分享到:
评论

相关推荐

    43丨单例模式(下):如何设计实现一个集群环境下的分布式单例模式?1

    单例模式是一种设计模式,旨在确保一个类只有一个实例,并提供全局访问点。在单例模式中,类的构造函数是私有的,防止外部直接创建对象,而是通过静态方法获取该类的唯一实例。单例模式的唯一性通常是在进程范围内,...

    单例模式单例模式单例模式

    ### 单例模式详解 #### 一、单例模式的概念 单例模式是软件开发中最基本的设计模式之一,尤其在Java编程中应用广泛。它的核心思想是确保一个类仅有一个实例,并提供一个全局访问点来获取该实例。这种模式特别适用...

    设计模式单例模式和工厂模式综合应用

    "设计模式单例模式和工厂模式综合应用"的主题聚焦于两种常用的设计模式:单例模式和工厂模式,并探讨它们如何协同工作来实现高效、灵活的代码结构。这个主题尤其适用于Java编程语言,因为Java的面向对象特性使得设计...

    C#单例模式详解 C#单例模式详解C#单例模式详解

    单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在C#中,单例模式常用于管理共享资源或控制类的实例化过程,以提高性能、节约系统资源,特别是在整个应用程序生命周期内只需要一...

    设计模式之单例模式(结合工厂模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类只有一个实例存在,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于管理共享资源,如数据库连接池、线程池或者配置文件等。结合工厂模式,...

    java单例模式实例

    单例模式是软件设计模式中的一种经典模式,用于确保一个类只有一个实例,并提供一个全局访问点。在Java中,有多种实现单例模式的方法,每种都有其特点和适用场景。接下来,我们将深入探讨这些实现方式。 首先,我们...

    单例模式详解~~单例模式详解~~

    单例模式是一种设计模式,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。在软件工程中,单例模式常用于控制资源的共享,比如数据库连接池、线程池或者日志系统等,这些资源通常需要全局唯一且高效地...

    使用C++11实现线程安全的单例模式

    在C++编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。线程安全的单例模式在多线程环境下尤其重要,因为不正确的实现可能导致多个线程创建多个实例,这违反了单例模式...

    设计模式——单例模式

    **设计模式——单例模式** 在软件工程中,设计模式是一种在特定场景下解决常见问题的标准方案,可以被复用并提升代码质量。单例模式是设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式...

    使用单例模式创建学生管理系统(饿汉式、懒汉式)

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java或类似的面向对象编程语言中,单例模式常用于管理共享资源,如数据库连接池、线程池或者配置文件等。在这个...

    7种单例模式

    单例模式是软件设计模式中的一种经典模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如控制共享资源、管理配置对象等。下面将详细介绍七种常见的单例模式实现...

    c++单例模式线程日志类

    在C++编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在这个特定的场景中,我们讨论的是一个实现了单例模式的日志类,该类专为多线程环境设计,具备日志等级控制、...

    单例模式实现mdi界面子窗体控制

    首先向关注过我这个系列...这立刻让我想到了最常用也是最简单最容易理解的一个设计模式 单例模式 何为 单例模式 ? 故名思议 即 让 类 永远都只能有一个实例。 由于 示例代码 比较简单 我也加了注释,这里就不在赘述

    几种单例模式demo

    单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在很多场景下都非常有用,比如控制资源的唯一性、管理共享配置或者创建昂贵的对象时避免频繁创建销毁。 ...

    Java 单例模式 工具类

    Java中的单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供全局访问点。在Java编程中,单例模式常用于控制资源的访问,比如数据库连接池、线程池或者日志对象等。本篇文章将深入探讨如何在Java中...

    单例模式(singleton)

    单例模式是软件设计模式中的一种,它的核心思想是确保一个类在整个系统中只有一个实例,并提供一个全局访问点。在Java或类似编程语言中,单例模式常常被用来管理资源,比如数据库连接、线程池或者配置信息,因为这些...

    Qt qml Singleton 单例模式

    在Qt的Qml环境中,单例模式是一种设计模式,它允许在整个应用程序中创建一个全局访问点,确保某个类只有一个实例存在。这样的设计模式在需要共享数据或者服务时非常有用,避免了多处创建相同对象导致的数据不一致或...

    设计模式之单例模式源码demo

    单例模式是软件设计模式中的经典模式之一,其主要目的是控制类的实例化过程,确保在应用程序的整个生命周期中,某个类只有一个实例存在。这样的设计通常适用于那些需要频繁创建和销毁,但资源消耗较大的对象,如...

    23钟设计模式之单例模式

    单例模式是一种常用的设计模式,它的核心思想是在整个应用程序中,一个类只能有一个实例存在。单例模式常用于控制资源的共享,例如数据库连接池、日志服务等。单例模式有多种实现方式,常见的包括懒汉式、饿汉式以及...

Global site tag (gtag.js) - Google Analytics