饿汉式

  • 饿汉式单例模式,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题,

因此可以省略synchronized关键字

  • 问题:如果只是加载本类,而不是要调用getInstance(),甚至永远没有调用,则会造成资源浪费
public class SingletonDemo1 {
//类初始化时,立即加载这个对象(没有延时加载的优势),,记载类时,天然的是线程安全的
private static SingletonDemo1 instance = new SingletonDemo1();
private SingletonDemo1(){ }; //方法没有同步,效率高
public static SingletonDemo1 getInstance(){
return instance;
} }

懒汉式

  • Lazy Load,延时加载,真正用到的时候再加载
  • 每次都得使用同步,synchronized,效率就底下了。
public class SingletonDemo2 {
//类初始化时,不初始化这个对象,(延时加载,真正用到的时候再创建)
private static SingletonDemo2 instance ;
private SingletonDemo2(){ }; //方法同步,效率低
public static synchronized SingletonDemo2 getInstance(){ if(instance==null){
instance= new SingletonDemo2();
}
return instance;
} }

双重检测锁

  • 双重检测判断
  • 使用volatile关键字,保证可见性
public class Singleton {
private volatile static Singleton sSingleton; private Singleton() {
} public static Singleton getSingleton() {
if (sSingleton == null) {
synchronized (Singleton.class) {
if (sSingleton == null) {
sSingleton = new Singleton();
}
}
}
return sSingleton;
}
}

静态内部类

  • 外部类没有static关键字,所以不会立即加载
  • 只有调用getInstance()时才会加载静态内部类,线程安全。instance前面加了static final关键字,因此保证了内存中只有这样一个实例存在,且只能赋值一次,final保证线程安全
  • 具有并发高效调用和延迟加载的双重优点
public class SingletonDemo3 {

    private static class SingletonClassInstance{
private static final SingletonDemo3 instance = new SingletonDemo3() ;
} private SingletonDemo3(){ } public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
} }

枚举实现

  • 实现简单
  • 枚举本身就是单例模式
public enum SingletonDemo4 {

    //枚举元素本身就是单例对象
INSTANCE; //添加自己需要的操作
public void singletonOperation(){ }
}

如何防止反射和反序列化漏洞

  • 反射可以破解上面几种(不包含枚举式)实现方式  --------------------------可以在构造方法中手动抛出异常控制
  • 反序列化可以破解上面几种(不包含枚举式)实现方式

-------可以通过定义readResolve()防止获得不同对象。
            --------反序列化时,如果对象所在类定义了readResolve(),定义返回哪个对象,实际是一种回调。

public class SingletonDemo5 {
//类初始化时,不初始化这个对象,(延时加载,真正用到的时候再创建)
private static SingletonDemo5 instance ;
private SingletonDemo5(){
if(instance !=null){
throw new RuntimeException();
}
} //方法同步,效率低
public static synchronized SingletonDemo5 getInstance(){
if(instance==null){
instance= new SingletonDemo5();
}
return instance;
} //反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不需要单独创建新的对象
private Object readResolve(){
return instance;
}
}

五种单例模式比较

单例对象占用资源少,不需要延时加载   -------枚举类好于饿汉式

单例对象占用资源大,需要延时加载      -------静态内部类好于懒汉式

设计模式之单例模式 Singleton实现的更多相关文章

  1. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

  2. 设计模式(4) -- 单例模式(Singleton)

    设计模式(4)  -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...

  3. 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)

    原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...

  4. 【设计模式】单例模式-Singleton

    [设计模式]单例模式-SingletonEnsure a class has only one instance, and provide a global point to access of it ...

  5. 设计模式之——单例模式(Singleton)的常见应用场景

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

  6. 设计模式之单例模式(Singleton Pattern)

    单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...

  7. 设计模式一: 单例模式(Singleton)

    简介 单例模式是属于创建型模式的一种(另外两种分别是结构型模式,行为型模式).是设计模式中最为简单的一种. 英文单词Singleton的数学含义是"有且仅有一个元素的集合". 从实 ...

  8. 设计模式之——单例模式(Singleton)的常见应用场景(转):

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

  9. java设计模式之 单例模式 Singleton

    static 的应用 单例模式 Singleton 单例:保证一个类在系统中最多只创建一个实例. 好处:由于过多创建对象实例,会产生过多的系统垃圾,需要GC频繁回收,由于GC会占用较大的系统资源,所有 ...

  10. 【设计模式】单例模式 Singleton Pattern

    通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance)  的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...

随机推荐

  1. 零基础逆向工程22_PE结构06_导入表

    导入表结构 typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; DWORD OriginalFirstTh ...

  2. django之模版的自定义函数

    - 自定义函数 simple_tag a. app下创建templatetags目录 b. 任意xxoo.py文件 c. 创建template对象 register d. __author__ = ' ...

  3. PHP实现正态分布的累积概率函数

    在实际项目中,遇到需要正态分布算法去计算一个数值在整体的分布区间,例如:  100,90,80,70,60,50,40,30,20,10共10个数,按从高到低的顺序排序,总数的10%分布区域为极高频, ...

  4. SQLServer 2012 报表服务部署配置(2)

    2.当系统打开"SQL Server安装中心",则说明我们可以开始正常的安装SQL Server 2012,可以通过"计划"."安装".&q ...

  5. Python各种参数类型

    1. Python的参数传递是值传递还是引 举例说明Python函数参数传递的几种形式,并说明函数传参是值传递还是引用传递 一.位置参数 调用函数时根据函数定义的参数位置来传递参数.例子: def p ...

  6. 从SAP客户主数据里直接创建商机(Opportunity)

    在SAP CRM Fiori的Account应用里,直接在Account页面创建商机: 在SAP Cloud for Customer里: 要获取更多Jerry的原创文章,请关注公众号"汪子 ...

  7. Python:numpy数组转换为json格式

    在python中,如何将一个numpy数组转换为json格式? 这是最近遇到的一个问题,做个笔记. 假设arr为numpy数组,将其转换为json格式: 总体思想是①首先转换为python的list, ...

  8. JDBC对数据库的简单操作

    /** * 获取数据库连接 */ public Connection GetConnection(){ Connection connection=null; try { Class.forName( ...

  9. 用户输入和while循环

    函数input()的工作原理 message=input('Tell me something,and I will repeat it back to you:') print(message) 编 ...

  10. 记录一次mysql中自定义获取UUID的函数

    循环方式一: DELIMITER :; drop function if exists test.fn_test:; create function test.fn_test() ) begin ) ...