饿汉式

  • 饿汉式单例模式,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. 【深度精讲】JFinal中的Ret和Kv工具类的区别,你用对了吗?

    在JFinal中有两个类Map的工具类,一个是有状态的Ret,一个是无状态的Kv,各种自己的应用场景,你用对了吗? 下面我们从多个方面来探究一下,JFinal针对这两个类的设计: 一.位置-com.j ...

  2. Hybrid框架安全隐患分析

    Hybrid框架安全隐患分析 目前我司移动端项目中各种app如雨后春笋般生根发芽层出不穷.而利用Hybrid框架确实可以减轻一部分移动端压力.并且做到灵活发版.但是其中的安全问题往往让人忽略. 针对A ...

  3. Python+selenium之键盘事件

    keuys()类提供键盘上所有的按键方法.send_keys()方法可以用来模拟键盘输入. from selenium import webdriver from selenium.webdriver ...

  4. selenium-Python之上传文件

    对于web 页面的上传功能实现一般有一下两种方式 普通上传:普通的附件上传是将本地文件的路径作为一个值放在input标签中,通过form表单将这个值提交给服务器 插件上传:一般是指基于flash.ja ...

  5. 洛谷 P1433 吃奶酪

    题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块 ...

  6. Java的三大特性之继承

    此处我会分为这几个部分来理解继承是怎么样的: 1.区分封装.继承和多态 2.区分限定词的范围 3.区分隐藏.覆盖.重载 4.继承的理解 5.一道面试题的原型 --------------------- ...

  7. java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config

    今天写SpringMvc时,遇到这样一个问题: java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config at org.sp ...

  8. BOM属性对象方法

    本文原链接:https://cloud.tencent.com/developer/article/1018747 BOM 1.window对象 2.location对象 3.history对象 BO ...

  9. 访问URI地址

    //发送消息到服务器 public string HttpConnectToServer(string ServerPage) { byte[] dataArray = Encoding.Defaul ...

  10. js中实现杨辉三角

    实现效果:杨辉三角 即: 提示用户输入要实现的杨辉三角行数: 请输入杨辉三角的行数: 8 代码实现后的效果如下: 1 1.1 1.2.1 1.3.3.1 1.4.6.4.1 1.5.10.10.5.1 ...