今天开始学习设计模式,借此机会学习并整理学习笔记。

设计模式是一门不区分语言的课程,什么样的编程语言都可以用到设计模式。如果说java语法规则比作武功招式的话,那么设计模式就是心法。

设计模式共有23种,常见的19种,最常用的9-10种。

设计模式分三种类型:创建型、结构型、行为型;

其中创建型包含单例设计模式、工厂模式、抽象工厂模式、原型模式、建造者模式;结构型包含代理模式、装饰器模式、适配器模式、外观模式、组合模式、享元模式、桥梁模式;行为型包含:策略模式、责任链模式、命令模式、中介者模式、模板方法模式、迭代器模式、访问者模式、观察者模式、解释器模式、备忘录模式、状态模式。

好了,凑字完毕,开始今天的学习整理

Singleton设计模式,就是单例设计模式。

单例设计模式有句顺口溜:单例一实例,私有构造器

单例设计模式分为饿汉式和懒汉式。

饿汉式是用户没有请求你的要求时,已经把这个实例提前创建出来了;

懒汉式则是需只有外部需要调用getInstance的时候,才回去初始化这个单例。

这样就有一个区别:

饿汉式:用空间换时间

懒汉式:用时间换空间

下面是具体代码实现:

singleton 单例设计模式
 1:饿汉式
饿汉式优缺点:
优点: 实现简单,没有多线程同步问题(默认条件下是线程安全的)
缺点:当类加载SingletonTest的时候,会初始化static的instance,静态变量被创建并分配内存空间,从此,这个static的instance对象便一直占着此段内存(即使你并没有使用该实例,当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
简单来说 用空间换时间

为什么在饿汉式中不讨论线程安全问题:
 因为类里面的静态实例都是由类加载器来负责初始化的,类加载器classLoader在出现类名的时候就会开始工作,把类的静态实例全部初始化,而且只初始化一次,所以一定是安全的,

public class Singleton {
    //静态一实例  将自身实例化对象设置为一个属性,并用static final修饰
    private static Singleton instance  = new Singleton();

//私有构造器
    private Singleton() {
        
    }
    
    //外部通过静态方法返回该实例
    public static Singleton getInstance() {
        return instance;
    }     
}

2:懒汉式
懒汉式优缺点:
优点:实现起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配内存空间,当getInstance()方法第一次调用的时,初始化instance变量,并分配内存空间。在某些条件下这种方式会节省内存。

缺点:在多线程环境中这种方法是完全错误的,根本不能保证单例的状态 需要添加synchronized(锁)

public class Singleton2 {
    //对象赋予null值 或者 不赋值  
    private static Singleton2 instance2;

//私有构造器
    prviate Singleton2() {
        
    }
    
    //外部获取实例对象  此时为了线程安全 需要使用synchronized(锁)
    public static synchronized Singleton2 getInstance2() {
        if(instance2 == null) {
            instance2 = new Singleton2();
        }
        return instance2;
    }       
}

3:如何兼顾饿汉式与懒汉式的优点:
 第一种:使用静态内部类的方法

优点:外部类加载时不予要立即加载内部类,内部类不被加载就不会初始化instance 故而占用内存。当Singleton 第一次加载时,并不需要去加载Singleton3handler只有当getInstance()方法第一次被 调用时,才会去初始化Instance,第一次调用getInstance()方法会导致虚拟机加载在SingletonHangdler类,这种方法不仅能确保线程安全,也能保证单例的唯一性,同时也延迟单例的实例化,

public class Singleton3 {
        //构建静态内部类
        private static class Singleton3Handler{
            private static Singleton3 instance3 = new Singleton3();
        }
        //私有构造器
        private  Singleton3() {
            
        }
        //外部获取对象
        public static Singleton3 getInstance() {
            return Singleton3.Singleton3Handler.instance3;
        }
}

第二种:使用枚举方式  
优点: 线程是安全的

public enum Singleton4{
        INSTANCE;
        public void method() {
            //TODO
        }
    }
 在任何情况下,它都是一个单例 我们可以直接 Singleton4.INSTANCE 引用

第三种:使用DCL模式     需要使用Volatile 关键字
双重锁懒汉式( Double Check Lock  简称 DCL )
优点:只有对象需要被使用的时候才创建,第一次判断instance21 == null 为了避免非必要枷锁,当第一次加载时才对实例进行枷锁在实例化。这样就可以节约内存空间,有可以保证线程安全。

缺点:但是,由于jvm存在乱序执行功能,DCL也会出现线程不安全的情况。

比如:  
      instance21  = new Singleton2;
      这个步骤,其实在jvm里面的执行分为三步:
      1:在堆内开辟内存空间
      2;在堆内存中实例化Singleton2里面的各个参数
      3:  把对象指向堆内存
      但是这个缺点在jdk1.6以后 只需要定义 为: private volatile  static Singleton5 instance5 = null;  就可以
      解决此问题  。  volatile确保instance每次在均在主内存中读取,这样虽然会牺牲一点效率。

public class Singleton5{
    // 对象一实例
    private volatile static Singleton5 instance5;
    //私有构造器
    private Singleton5() {
        
    }
    //DCL懒汉式
    public static Singleton5 getInstance() {
        if(instance5==null) {
            synchronized(Singleton5.class){
                if(instance5 == null) {
                    instance5 = new Singleton5();
                }
            }
        }
        return instance5;
    }
}

需要注意的是:

  需要延迟加载的情况下使用第一、第二种;

  需要防止序列化问题、反射攻击使用第三种。

才疏学浅,如有错误,恳请指教!

QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/error.png)}.QUZHUANPAN-PLUGIN-VALIDATE-PASS>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/success.png)}.QUZHUANPAN-PLUGIN-VALIDATE-UNCERTAINTY>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/uncertainty.png)}.QUZHUANPAN-PLUGIN-VALIDATE-LOCK>QUZHUANPAN-PLUGIN-TIPS::before{content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/lock.png)}
-->
QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/error.png)}.QUZHUANPAN-PLUGIN-VALIDATE-PASS>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/success.png)}.QUZHUANPAN-PLUGIN-VALIDATE-UNCERTAINTY>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/uncertainty.png)}.QUZHUANPAN-PLUGIN-VALIDATE-LOCK>QUZHUANPAN-PLUGIN-TIPS::before{content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/lock.png)}
-->
QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/error.png)}.QUZHUANPAN-PLUGIN-VALIDATE-PASS>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/success.png)}.QUZHUANPAN-PLUGIN-VALIDATE-UNCERTAINTY>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/uncertainty.png)}.QUZHUANPAN-PLUGIN-VALIDATE-LOCK>QUZHUANPAN-PLUGIN-TIPS::before{content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/lock.png)}
-->
QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/error.png)}.QUZHUANPAN-PLUGIN-VALIDATE-PASS>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/success.png)}.QUZHUANPAN-PLUGIN-VALIDATE-UNCERTAINTY>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/uncertainty.png)}.QUZHUANPAN-PLUGIN-VALIDATE-LOCK>QUZHUANPAN-PLUGIN-TIPS::before{content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/lock.png)}
-->
QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/error.png)}.QUZHUANPAN-PLUGIN-VALIDATE-PASS>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/success.png)}.QUZHUANPAN-PLUGIN-VALIDATE-UNCERTAINTY>QUZHUANPAN-PLUGIN-TIPS::before {content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/uncertainty.png)}.QUZHUANPAN-PLUGIN-VALIDATE-LOCK>QUZHUANPAN-PLUGIN-TIPS::before{content: '';background-image: url(http://www.quzhuanpan.com/media/tampermonkey/tips/lock.png)}
-->

设计模式笔记(一):Singleton 设计模式的更多相关文章

  1. 设计模式 笔记 单例模式 Singleton

    //---------------------------15/04/09---------------------------- //Singleton 单例模式-----对象创建型模式 /* 1: ...

  2. [设计模式] .NET设计模式笔记 - 有多少种设计模式

    .NET下的23中设计模式. ※创建型模式篇 ●单件模式(Single Pattern) ●抽象工厂模式(Abstract Factory) ●建造者模式(Builder Pattern) ●工厂方法 ...

  3. php设计模式笔记:单例模式

    php设计模式笔记:单例模式 意图: 保证一个类仅有一个实例,并且提供一个全局访问点 单例模式有三个特点: 1.一个类只有一个实例2.它必须自行创建这个实例3.必须自行向整个系统提供这个实例 主要实现 ...

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

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

  5. 从C#的Singleton设计模式

    近来,我在学习如何在C#语言中使用设计模式中读到一些资料,其中有关Singleton设计模式引起了我的注意. 学过设计模式的开发者都知道Singleton模式.我想简要地解释一下这个设计模式是为那些尚 ...

  6. [设计模式] 5 单例模式 singleton

    转处 http://blog.csdn.net/wuzhekai1985 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多 ...

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

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

  8. Singleton设计模式的一种见解

    单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了,这可能也是面试中问得最多的一个设计模式了.这个设计模式主要目的是想在整个系统中只能出现一个类的实例.这样做当然是有必然的,比 ...

  9. 深入浅出单实例Singleton设计模式

    深入浅出单实例Singleton设计模式 陈皓 单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了,这可能也是面试中问得最多的一个设计模式了.这个设计模式主要目的是想在整个系统 ...

随机推荐

  1. 使用Counter进行计数统计

    使用Counter进行计数统计 想必大家对计数统计都不陌生吧!,简单的说就是统计某一项出现的次数.实际应用中很多需求都需要用到这个模型,如检测样本中某一值出现的次数.日志分析某一消息出现的频率分析文件 ...

  2. 【CSS】Houdini, CSS的成人礼

    前情提要 CSS:老板,你看ES9,ES10都出来了,您看我的事情什么时候... W3C: 这不是正在走着流程嘛!小C你不要心急! W3C:(语重心长)你看啊,我们先(1)提个开发提案章程, 然后再批 ...

  3. Redis缓存,持久化,高可用

    一,Redis作缓存服务器 ​ 本篇博客是接着上一篇博客未分享完的技术点. ​ redis作为缓存服务器是众多企业中的选择之一,虽然该技术很成熟但也是存在一定的问题.就是缓存带来的缓存穿透,缓存击穿, ...

  4. copy好文“IT34岁危机破解心法”

    在博客园中偶然发现一个好文,收藏并记录以下.在工作中更多的从企业单位用人角度去思考,或许能在职场及职业规划中更加的游刃有余,有的放矢.下面是原文. 本文题目虽是“IT人34岁危机”破解心法,但内容同样 ...

  5. Postman系列五:Postman中电商网站cookie、token检验与参数传递实战

    一:Postman中电商网站cookie实战 Postman接口请求使用cookie两种方式: 1.直接在header(头域)中添加cookie,适用于已知请求cookie头域的情况 2.使用Post ...

  6. [转]Android中设置TextView的颜色setTextColor

    [转自]http://txlong-onz.iteye.com/blog/1249609 Android中设置TextView的颜色setTextColor android中设置TextView的颜色 ...

  7. SqlServer关于“无法删除数据库 "XXXX",因为该数据库当前正在使用”问题的解决方案

    引言 在项目中,通过使用SQL语句“DROP DATABASE [数据库名]”删除数据时,一直出现“无法删除数据库 "XXXX",因为该数据库当前正在使用”的错误信息,经测试在Sq ...

  8. 一看就懂-Docker容器化

    一.Docker简介 1.1 什么是docker docker的英文意思是 码头工人,意思就是搬运东西的意思,其实这和docker的特点是一样的,docker提供的就是一种容器化搬运东西(我们的软件. ...

  9. crontab使用方法

    一.crontab基本用法 1.1 cron服务 cron是一个linux下 的定时执行工具,可以在无需人工干预的情况下运行作业. service crond start //启动服务 service ...

  10. 约瑟夫环问题:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

    首先,我最大的学习来源不是百度而是我群友~~在这里表白一波我热爱学习的群友们!然后今天群里突然有人提出了题目的这个问题:有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出 ...