文档章节

单例模式Singleton

Gnepux
 Gnepux
发布于 2016/11/28 00:42
字数 682
阅读 3
收藏 0

单例模式定义

确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式类图

类图说明

  • Client:高层客户类
  • Singleton:单例类

实现单例模式的要点

  • 构造函数不对外开放,一般为Private
  • 通过一个静态方法或枚举返回单例类对象
  • 确保单例类的对象有且只有一个,尤其在多线程环境下
  • 确保单例类对象在反序列化时不会重新构建对象

单例模式的实现方式

  • 饿汉:在声明时就初始化
    /** 
     * 饿汉单例 
     */
    public class MySingleton {
        // 饿汉单例,在声明时就初始化
        private static MySingleton ourInstance = new MySingleton();
    
        public static MySingleton getInstance() {
            return ourInstance;
        }
    
        private MySingleton() {
        }
    }
  • 懒汉:只有在使用时才会实例化,在一定程度上节省了资源;缺点是第一次加载时需要及时进行实例化,反应稍慢,最大的问题是每次调用getInstance都要进行同步,造成不必要的同步开销。这种模式一般不建议采用。
    /**
     * 懒汉单例
     */
    public class MySingleton {
        private static MySingleton ourInstance;
        
        public static synchronized MySingleton getInstance() {
            // 懒汉单例,只有在使用才会实例化
            if (ourInstance == null) {
                ourInstance = new MySingleton();
            }
            return ourInstance;
        }
    
        private MySingleton() {
        }
    }
  • DCL:Double Check Lock。优点是既能够在需要时实例化单例,又能保证线程安全,且单例对象初始化后调用getInstance不进行同步锁。
    /**
     * Double Check Lock(DCL)
     */
    public class MySingleton {
        private static MySingleton ourInstance = null;
    
        private MySingleton() {};
    
        public static MySingleton getInstance() {
            // 避免不必要的同步
            if (ourInstance == null) {
                synchronized (MySingleton.class) {
                    // 创建实例
                    if (ourInstance == null) {
                        ourInstance = new MySingleton();
                    }
                }
            }
            return ourInstance;
        }
    }
  • 静态内部类:当第一次加载Singleton类时并不会初始化,只有在第一次调用时才会初始化。因此,第一次调用getInstance方法会导致虚拟机加载SingleHolder类,这种方式不仅能够确保线程安全,也能保证单例对象的唯一性,同时也延迟了单例实例化,所以这是推荐使用的单例模式实现方式
    /**
     * 静态内部类单例模式
     */
    public class MySingleton {
    
        private MySingleton() {};
    
        public static MySingleton getInstance() {
            return SingletonHolder.ourInstance;
        }
    
        /**
         * 静态内部类
         */
        private static class SingletonHolder {
            private static MySingleton ourInstance = new MySingleton();
        }
    }
  • 枚举单例:枚举单例是线程安全的,并且在任何情况下它都是一个单例。且无法通过反序列化得到对象。
    /**
     * 枚举单例
     */
    public enum SingletonEnum {
        INSTANCE;
        public void dosomething() {
            System.out.println("do sth.");
        }
    }
  • 使用容器实现单例
    /**
     * 使用容器实现单例模式
     */
    public class SingletonManager {
        private static Map<String, Object> objMap = new HashMap<>();
    
        private SingletonManager() {}
    
        public static void registerService(String key, Object instance) {
            if (!objMap.containsKey(key)) {
                objMap.put(key, instance);
            }
        }
    
        public static Object getService(String key) {
            return objMap.get(key);
        }
    }

Android中的应用:

getSystemService 通过容器实现单例 

https://my.oschina.net/u/3026396/blog/808207

 

© 著作权归作者所有

Gnepux
粉丝 3
博文 96
码字总数 77557
作品 0
南京
私信 提问
设计模式1——Singleton设计模式

Singleton单例模式是最简单的设计模式,它的主要作用是保证在程序运行生命周期中,使用了单例模式的类只能有一个实例对象存在。单例模式实现了类似C语言中全局变量的功能,单例模式常用于注册...

小米米儿小
2013/12/05
0
0
23种设计模式(1):单例模式

定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 类型:创建类模式 类图: 类图知识点: 1.类图分为三部分,依次是类名、属性、方法 2.以<<开头和以>>结尾的为注释...

LCZ777
2014/07/05
0
0
为什么java中用枚举实现单例模式会更好

枚举单例是java中使用枚举提供一个实例对象来实现单例模式的一种新方法,虽然单例模式在java中早已存在,但枚举单例实际上从java5引入枚举作为它的关键特性之后相对来说还是一个新的概念,这...

zhoujy
2013/06/01
0
0
C++设计模式——一个基于C++11的万用单例模板类

单例模式概述 单例模式(Singleton),是设计模式里面最常见、最常用的设计模式,也是最简单、最容易实现的设计模式。单例模式的目的很简单,创建一个全局唯一的对象(类or变量)。 简单代码...

GodMayCry
2017/11/06
0
0
Java程序员从笨鸟到菜鸟之(三十三)大话设计模式(三)单例模式

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说...

长平狐
2012/11/12
120
0

没有更多内容

加载失败,请刷新页面

加载更多

【AI实战】手把手教你深度学习文字识别(文字检测篇:基于MSER, CTPN, SegLink, EAST等方法)

文字检测是文字识别过程中的一个非常重要的环节,文字检测的主要目标是将图片中的文字区域位置检测出来,以便于进行后面的文字识别,只有找到了文本所在区域,才能对其内容进行识别。 文字检...

雪饼
今天
15
0
思维导图XMind 8 Pro 绿化方法(附序列号)

按部就班: Step 1 -全新下载最新版本的 Xmind 8(注必须是英文官方的版本,中文代{过}{滤}理网站的版本修改过,无法使用pj); Step 2 -安装完毕后,点击文末的下载按钮下载pj补丁文件包,将...

一只小青蛙
今天
10
0
数据结构(ER数据库)设计规范

表命名规范 表命名的规则分为3个层级,层级之间通过_分割,例如b_r_identity、d_l_identity。规约为: [leavel]_[type]_[name] [leavel] 表示数据库表的层级和功能,分为: s:业务无关的系统...

随风溜达的向日葵
今天
10
0
阿里Sentinel控制台源码修改-对接Apollo规则持久化

https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel 动态规则扩展 https://github.com/alibaba/Sentinel/wiki......

jxlgzwh
昨天
14
0
在Linux系统中创建SSH服务器别名

如果你经常通过 SSH 访问许多不同的远程系统,这个技巧将为你节省一些时间。你可以通过 SSH 为频繁访问的系统创建 SSH 别名,这样你就不必记住所有不同的用户名、主机名、SSH 端口号和 IP 地...

老孟的Linux私房菜
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部