zoukankan      html  css  js  c++  java
  • JAVA设计模式——(1)单例模式

    什么是单例模式

    单例模式,顾名思义,就是整个系统就只有一个实例存在。

    特点

    1. 单例类只能有一个实例。
    2. 单例类必须自己创建自己的唯一实例。
    3. 单例类必须给所有其他对象提供这一实例。

    讲的通俗一点,我们拿女娲造人来举例:

    我们先写一个女娲类:

    1 public class N_Wa {
    2 
    3 }

    很明显,任何人都不能创造女娲,所以女娲的构造应该是私有的:

    1 public class N_Wa {
    2     private N_Wa() {}   // 构造方法私有化
    3 }

    有人可能要质疑:那女娲应该是谁创造的?
    这个问题千百万年来都没有人能解开过,所以在我们的潜意识中认为:神是自己创造自己的!

    1 public class N_Wa {
    2     private static final N_Wa n_wa = new N_Wa();   // 神自己创造自己
    3     private N_Wa() {}     // 构造方法私有化
    4 }

    private 保证了女娲的私有性,毕竟这个世界上没有人见过女娲。
    static 保证了女娲的静态性,她与类共存亡。
    final 保证了女娲是“终极”常量,不可能再被修改。

    女娲已经出来了,接下来干什么呢?
    当然就是请她开始造人啦:

    1 public class N_Wa {
    2     private static final N_Wa n_wa = new N_Wa();   // 神自己创造自己
    3     private N_Wa() {}     // 构造方法私有化
    4     public static N_Wa getInstance() {    // 请求女娲
    5         return n_wa;
    6     }
    7 }

    getInstance 和 new?
    new 是重新创建一个对象,且只能单次使用。
    getInstance 是没有对象的时候创建对象,有了之后就保留在内存中,下次就不用再重新创建了,因此它的对象一定是static的。

    这样一来,只需要调用 N_Wa.getInstance(); 女娲就请过来了,而且不论是谁,请来的都是同一个女娲,也就是我们构造的“终极”常量:n_wa。当然你还可以往里面加入其它的功能(造人功能未写出)。

    到此为止,我们就已经学会了单例模式——“饿汉模式”,即我们先把女娲给造好,需要的时候直接用就好了。

    随之而来的是另一个问题:要是我们根本没有用到女娲呢?那不是白造了?于是又出现了一种叫“懒汉模式”:

     1 public class N_Wa {
     2     private static N_Wa n_wa;   // 这里并没有new一个女娲
     3     private N_Wa() {}     // 构造方法私有化
     4     public static N_Wa getInstance() {    // 请求女娲
     5         if(n_wa == null) {
     6             n_wa = new N_Wa();
     7         }
     8         return n_wa;
     9     }
    10 }

    可以发现,我们不再是提前造女娲了,而是需要的时候再去造她(实例化),但这样子的坏处就是每次都要重新造一次女娲,所以速度肯定不如之前的“饿汉模式”。而且有个大问题,就是一旦有很多人同时请女娲的话,依然可能造成多个神的情况。

    所以我们让这些人排队?看起来挺有道理,但仔细想想,有些人做事总是拖拖拉拉,毛手毛脚的,万一给让它排到前面去了,那后面的人不得等半天吗?等下队伍直接排出地球外了,所以我们干脆让他们直接抢,谁抢到就是谁的,这样一直抢下去:

     1 public class N_Wa {
     2     private static N_Wa n_wa;   // 这里并没有new一个女娲
     3     private N_Wa() {}     // 构造方法私有化
     4     public static N_Wa getInstance() {    // 请求女娲
     5         if(n_wa == null){      // 代表还没有人抢到
     6             synchronized (N_Wa.class) {    // 放他们进去抢
     7                 if(n_wa == null) {       // 第一个抢到的给他 new一个然后返回
     8                     n_wa = new N_Wa();
     9                 }
    10             }
    11         }
    12         return n_wa;
    13     }
    14 }

    synchronized 是一种同步锁,可以防止同步发生,通俗来讲就是第一个人先用,这时锁被锁上,等他用完,锁再打开,以此类推。只有当锁是开着的,才能轮到下一个人。

    到此为止,最基础的两种“恶汉模式”和“懒汉模式”就完成了,单例模式还有其它的一些变种,但思想上都大同小异,我们需要灵活运用,发挥出最大的价值!

  • 相关阅读:
    Javaweb实现表单数据和多文件上传
    Java一般命名规范
    基于微信公众号的答题投票系统——项目开发心得体会记录
    C语言实现对二叉树的操作
    C语言使用链表实现学生信息管理系统
    C语言实现对队列的基本操作
    C语言使用顺序表实现对学生信息的管理系统
    PHP实现周和月起止时间计算方法
    IOC容器和注入方式
    Spring简介+HelloWorld
  • 原文地址:https://www.cnblogs.com/Satan666/p/12670347.html
Copyright © 2011-2022 走看看