美文网首页
设计模式之一单例设计模式

设计模式之一单例设计模式

作者: 执着的瓶子 | 来源:发表于2017-12-05 17:18 被阅读0次

    一、使用场景

    单例设计模式是应用最广的设计模式,例如:当创建一个对象需要消耗过多的资源,如要访问IO或数据库等资源,这时就要考虑用单例模式;在一个应用中,应该只有一个ImageLoader实例,这个ImageLoader中又有线程池、缓存系统、网络请求等,很消耗资源,一般用单例模式。

    二、如何实现

    1、构造函数私有化。

    2、通过静态方法或者枚举返回单例对象。

    3、确保单例对象有且只有一个,尤其是在多线程环境下。

    4、确保单例对象在反序列化下不会重新构建对象。

    三、代码实现

    1、饿汉单例模式

    public class Singleton {

        private static final Singleton instance=new Singleton();

        private Singleton() {

       }

        public static Singleton getInstance() {

                      return instance;

         }

    }

    2、懒汉式

    懒汉单例模式的优点是单例只有在使用时才会初始化,在一定程度上节约了资源。缺点是第一次加载时需要及时进行实例化,反应稍慢,最大的问题是每次调用getInstance都进行同步,造成不必要的同步开销,不建议使用。

    public class Singleton {

          private static Singleton instance;

          private Singleton(){

        }

          public static Synchronized Singleton getInstance(){

               if(instance==null){

                       instance=new Singleton();

              }

             return instance;

         }

    }

    3、Double Check Load(DCL)

    优点是既能在需要时才初始化单例,又能保证线程安全,且单例模式初始化时调用getInstance不进行同步锁。缺点是在第一次加载时反应稍慢,由于java 内存模型的原因偶尔会加载失败,在高并发环境下也存在一定缺陷,但是概率较小。除非代码并发场景较复杂,或者在JDK 6版本以下,否则该种模式一般满足条件。该种模式也是使用较多的模式。

    public class Singleton {

          private static Singleton instance=null;

          private Singleton(){

       }

         public static Singleton getInstance(){

             if(instance==null){

                  synchronized(Singleton.class){

                        if(instance==null){

                               instance=new Singleton();

                       }

                }

            }

              return instance;

        }

    }

    4、静态内部类单例模式

    此种方法解决DCL模式不能在线程并发复杂情况下使用问题,此为推荐使用模式。

    public class Singleton {

         private Singleton() {

        }

         public static Singleton getInstance() {

                 return SingletonHolder.singleton;

       }

    /**

    *静态内部类

    */

          private static class SingletonHolder {

               private static fina lSingleton singleton=new Singleton();

        }

    }

    5、枚举单例

    此种方法写法简单,线程安全,并且防止反序列化重新生成对象。

    publc enum SingletonEnum{

    INSTANCE;

    }

    以上构建单例模式方法中,为了避免反序列化重新生成对象,加入以下方法

    private Object readResolve() throws ObjectSteamException{

    return instance;

    }

    6、使用容器实现单例

    这种方式使得我们可以管理多种类型的单例,并且使用时可以用统一的接口进行获取操作,降低用户使用成本,也对用户隐藏了具体实现,降低了耦合度。

    public class SingletonManager {

         private static Map objMap = new HashMap();

         private SingletonManager(){}

         public static void registerService(String key,Object instance){

                  if(!objMap.containsKey(key)){

                           objMap.put(key,instance);

             }

    }

         public static ObjectgetService(String key){

                      return objMap.get(key);

       }

    }

    不管以哪种方式实现单例模式,其核心都是构造器私有化,并且通过静态方法获取唯一实例,在获取过程中必须保证线程安全、防止反序列化重新生成实例等问题。当然,选择那种方式,取决于项目本身。

    相关文章

      网友评论

          本文标题:设计模式之一单例设计模式

          本文链接:https://www.haomeiwen.com/subject/rwecixtx.html