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. Mysql 日期加减

    mysql表中有一些字段是显示日期的.因为各种需要,需要将它时间往后调整1年. mysql 日期增加一年的更新语句更新的语句如下:     UPDATE table SET date = DATE_A ...

  2. Thinkphp语句拼接

    例如查询Stu表中年龄大于18,或者身高低于180cm的男性(1为男性),(例子不太好标题有可能不符,望见谅) $where['age'] = array("gt",18); $w ...

  3. Cuda9.2发布

    经过一次跳票,没有很多人注意(才怪)的cuda9.2终于发布了,官方介绍如下: CUDA 9.2 includes updates to libraries, a new library for ac ...

  4. 常用的OO设计原则

    常用的OO设计原则: 1 封装变化:找出应用中可能需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起. 2 针对接口编程,而不是针对实现编程. 3 多用组合,少用继承. 4 松耦合:为了 ...

  5. VideoView 监听视频格式不支持时的错误。

    视频播放格式不支持的处理https://www.cnblogs.com/ygj0930/p/7737209.html 不处理的情况下,默认会有弹框提示:不支持该视频格式. mVideoView.set ...

  6. IOC 和DI(转载)

    IOC 是什么? Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内 ...

  7. NodeJs学习相关网址

    node官方中文 https://nodejs.org/zh-cn/   Node.js 中文网 https://nodejs.org/zh-cn/   Node.js 教程 | 菜鸟教程 http: ...

  8. 646. Maximum Length of Pair Chain 最长的链条长度

    [抄题]: You are given n pairs of numbers. In every pair, the first number is always smaller than the s ...

  9. PHP pthread 多线程 案例

    <?php /** *检测http服务是否可以正常访问 *启动三个线程执行任务 */ class taskWork extends Thread { public $url = ''; //检测 ...

  10. CentOS7中firewall防火墙详解和配置,.xml服务配置详解

    修改防火墙配置文件之前,需要对之前防火墙做好备份 重启防火墙后,需要确认防火墙状态和防火墙规则是否加载,若重启失败或规则加载失败,则所有请求都会被防火墙 1. firewall-cmd --state ...