1. 定义

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

2. 使用场景

确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个。例如,创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源,这时候就需要考虑使用单例模式。

3. 机制

创建一个独一无二觉得的对象,有多种方式。但是不管你如何创建一个单例对象,都必须要确保其他开发人员不能创建该单例对象的新的实例。

那么如何做到这一点呢?  答:为了避免其他开发人员实例化你定义的类,可以创建唯一一个构造函数,并将其设置为私有的访问权限。注意,如果创建了其他非私有的构造函数,或者没有创建任何构造函数,其他对象都能够实例化改类。

设计一个单例类的时候,需要确定何时实例化该类的单例对象。一种做法是创建这个类的实例,并将它作为该类的静态成员变量。例如:

private static Factory factory = new Factory();

然后通过一个公共的getFactory()静态方法获得该类的唯一实例。实例代码:

public class Factory{
    private static Factory factory = new Factory ();
    public static Factory getFactory() {
        return factory;
    }
    private Factory() {}
}

如果不希望提前创建单例实例,还可以在第一次需要的时候,延迟初始化它。

if (factory == null)
    factory = new Factory();

延迟不延迟有哪些方面的区别呢? 为什么实例化还有延迟和非延迟?   一般延迟实例化对象有两个原因: 1. 在静态初始化的时候,没有足够的信息对单例对象进行初始化。  2. 选择延迟初始化单例对象与获取资源有关,如数据库连接,没有使用的需求,就没有必要实例化该单例对象。

3. 单例与线程

如果想在多线程环境下延迟初始化一个单例模型,必须避免多个线程同时初始化该单例对象。在多线程环境下,无法保证在其他线程开始执行该方法时,当前线程已经完整的执行完该方法。这可能出现两个线程同时初始化一个单例对象的情况。为了避免这种情况,需要使用双重校验锁机制(Double Check Lock)去协调不同线程对同一方法的执行。

public class SingletonClass {
    private static SingletonClass instance = null;
    public static SingletonClass getInstance() {
        if(instance==null) {
            synchronized(SingletonClass.class) {
                if(instance==null) {
                    instance=new SingletonClass();
                }
            }
        }
        return instance;
    }
    private SingletonClass() {}
}

单例模式或许是最负盛名的一个设计模式,但是很容易被误用,不要让单例作为创建全局变量的一种花哨方法。因为单例会引入耦合,应减少使用单例模式的类的数量。最好的方式是:类只知道与它协作的对象,不必了解它所需要的限制。 需要注意的是:对象具有唯一性,不代表使用了单例模式。

4. 推荐使用的单例模式实现方式

在应用单例模式时,我们知道懒汉模式、饿汉模式、双重检验锁模式。这些实现方式都有各自的特点和缺陷,其中双重校验锁算性是应用最为广泛的,但是也不是完美的。《Java并发编程实践》这本书给出来一个推荐的实现方式:

public class Singleton {
       // 构造函数
       private Singleton() {}
  
       public static Singleton getInstance(){
      return SingletonHloder.sInstance;
       }

    // 静态内部类
      private static class SingletonHloder {
      private static final Singleton sInstance = new Singleton();
     }
}    

实现方式解读:

当第一次加载Singletion类时并不会初始化sInstance,只有在第一次调用Singleton的getInstance方法时才会导致sInstance被初始化。因此,第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够确保线程安全,也能保证单例对象的唯一性,同时也延迟了单例的实例化,所以这是推荐使用的单例模式的实现方式。

设计模式总结(Java)—— 单例模式的更多相关文章

  1. 【Java设计模式】java单例模式

    解释一下什么是单例模式:     单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例.在计算机系统中,线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.这些 ...

  2. Java设计模式之《单例模式》及应用场景

    摘要: 原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该 ...

  3. Java设计模式之【单例模式】

    Java设计模式之[单例模式] 何为单例 在应用的生存周期中,一个类的实例有且仅有一个 当在一些业务中需要规定某个类的实例有且仅有一个时,就可以用单例模式 比如spring容器默认初始化的实例就是单例 ...

  4. Java设计模式中的单例模式

    有时候在实际项目的开发中,我们会碰到这样一种情况,该类只允许存在一个实例化的对象,不允许存在一个以上的实例化对象,我们将这种情况称为Java设计模式中的单例模式.设计单例模式主要采用了Java的pri ...

  5. Java设计模式学习01——单例模式(转)

    原地址:http://blog.csdn.net/xu__cg/article/details/70182988 Java单例模式是一种常见且较为简单的设计模式.单例模式,顾名思义一个类仅能有一个实例 ...

  6. 【设计模式】Java设计模式 - 单例模式

    [设计模式]Java设计模式 - 单例模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 分享学习心得,欢迎指正,大家一起学习成长! 原创作品,更多关注我CSDN: ...

  7. 用java单例模式实现面板切换

    1.首先介绍一下什么是单例模式: java单例模式是一种常见的设计模式,那么我们先看看懒汉模式: public class Singleton_ { //设为私有方法,防止被外部类引用或实例 priv ...

  8. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  9. 深入Java单例模式【转载】

    在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就单例设计模式详细的探讨一下.   所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在 ...

  10. 【转载】深入Java单例模式

    原文出处:http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容易出现问题.下面就 ...

随机推荐

  1. HttpWebResponse远程服务器返回错误: (500) 内部服务器错误 的解决办法

    在工作中用C#开发了一个小程序,不断访问去请求一个网站的页面,在循环过程中有时会报“远程服务器返回错误: (500) 内部服务器错误”,有时不会,出现的时机也不太一样.开始以为是网站的问题,后来网站是 ...

  2. CentOS6.5搭建OpenVas完全搭建手册(搭建过程总结及小记)

    一.OpenVAS 介绍 1.关于OpenVAS OpenVAS(Open Vulnerability Assessment System)是一套开源的漏洞扫描系统,早期Nessus 是其中一个最流行 ...

  3. 使用jQuery+huandlebars遍历数组嵌套数组

    兼容ie8(很实用,复制过来,仅供技术参考,更详细内容请看源地址:http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) & ...

  4. PXC 搭建高可用集群

    (1).PXC集群注意事项 1.PXC集群只支持innodb引擎 2.

  5. JAVA中float与double的区别

    float是单精度类型,精度是8位有效数字,取值范围是10的-38次方到10的38次方,float占用4个字节的存储空间 double是双精度类型,精度是17位有效数字,取值范围是10的-308次方到 ...

  6. 89. Gray Code返回位运算的所有生成值

    [抄题]: The gray code is a binary numeral system where two successive values differ in only one bit. G ...

  7. 回溯算法_ BackTracking

     目前还存在的疑问: 1. 所谓的该分支满足条件之后就回退到上一层节点,可是加谁呢? x[i+1]  ?? 加到 N, 不满足target sum条件就返回上一级(同时改变上一级数为 i+1...纵向 ...

  8. vscode快捷键的中文版

    自己整理了一份vscode快捷键的中文版本

  9. Mouse Detected Problem

    通常分三种情形: 鼠标完全不工作鼠标工作一段时间后不工作鼠标的按钮或者滚轮不工作 必要提交信息:1.鼠标的具体厂商和型号2.鼠标连接PC方式:串口.PS/2.USB或无线USB等:3.鼠标的工作机制: ...

  10. Codeforces Round #436 (Div. 2)C. Bus 模拟

    C. Bus time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard input out ...