zoukankan      html  css  js  c++  java
  • java设计模式之单例模式

      Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。

      我们在浏览BBS、SNS网站的时候,常常会看到“当前在线人数”这样的一项内容。对于这样的一项功能,我们通常的做法是把当前的在线人数存放到一个内存、文件或者数据库中,每次用户登录的时候,就会马上从内存、文件或者数据库中取出,在其基础上加1后,作为当前的在线人数进行显示,然后再把它保存回内存、文件或者数据库里,这样后续登录的用户看到的就是更新后的当前在线人数;同样的道理,当用户退出后,当前在线人数进行减1的工作。所以,对于这样的一个需求,我们按照面向对象的设计思想,可以把它抽象为“在线计数器”这样一个对象。

      网站代码中凡是用到计数器的地方,只要new一个计数器对象,然后就可以获取、保存、增加或者减少在线人数的数量。不过,我们的代码实际的使用效果并不好。假如有多个用户同时登录,那么在这个时刻,通过计数器取到的在线人数是相同的,于是他们使用各自的计数器加1后存入文件或者数据库。这样操作后续登陆的用户得到的在线人数,与实际的在线人数并不一致。所以,把这个计数器设计为一个全局对象,所有人都共用同一份数据,就可以避免类似的问题,这就是我们所说的单例模式的其中的一种应用。

      引用设计模式之禅里面的例子:

         第一种方式:

      

    package com.cbf4life.singleton1;
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 中国的历史上一般都是一个朝代一个皇帝,有两个皇帝的话,必然要PK出一个皇帝出来
    */
    public class Emperor {
    private static Emperor emperor = null; //定义一个皇帝放在那里,然后给这个皇帝名字
    private Emperor(){
    //世俗和道德约束你,目的就是不让你产生第二个皇帝
    }
    public static Emperor getInstance(){
    第 12 页
    您的设计模式
    if(emperor == null){ //如果皇帝还没有定义,那就定一个
    emperor = new Emperor();
    }
    return emperor;
    }
    //皇帝叫什么名字呀
    public static void emperorInfo(){
    System.out.println("我就是皇帝某某某....");
    }
    }
    

    但是一种方式有一个缺陷,

      假如现在有两个线程A和线程B,线程A执行到 this.singletonPattern = new SingletonPattern(),正在申请内存分配,可能需要0.001微秒,就在这0.001微秒之内,线程B执行到if(this.singletonPattern == null),你说这个时候这个判断条件是true还是false?是true,那然后呢?线程B也往下走,于是乎就在内存中就有两个SingletonPattern的实例了,看看是不是出问题了?如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!最重要的是你从代码上还看不出什么问题,这才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?有很多种方案,我就说一种,能简单的、彻底解决问题的方案

    第二种

    package com.cbf4life.singleton3;
    /**
    * @author cbf4Life cbf4life@126.com
    * I'm glad to share my knowledge with you all.
    * 通用单例模式
    */
    @SuppressWarnings("all")
    public class SingletonPattern {
    private static final SingletonPattern singletonPattern= new SingletonPattern();
    //限制住不能直接产生一个实例
    private SingletonPattern(){
    }
    public synchronized static SingletonPattern getInstance(){
    return singletonPattern;
    }
    }
    
  • 相关阅读:
    Qt 学习之路:Canvas
    Qt 学习之路:模型-视图高级技术
    Qt 学习之路 :视图代理
    Qt 学习之路 :动态视图
    Qt 学习之路 :Repeater
    Qt 学习之路 :Qt Quick Controls
    mysql-gdb--oracle
    redis-BOOK
    2016qconbeijing
    LINUX 内核月报 taobao
  • 原文地址:https://www.cnblogs.com/wangchy0927/p/2620042.html
Copyright © 2011-2022 走看看