专栏首页每日分享java架构小知识java设计模式-单例模式

java设计模式-单例模式

单例模式

其定义为:单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的一个类只有一个实例。即一个类只有一个对象实例。

实现单例模式的方式

单例模式的实现方式有很多,主要有饿汉模式,懒汉模式,静态内部类,注册登记模式以及通过实现序列化也可以实现单例模式。

饿汉模式

public class Hungry {

    private Hungry(){}
  
    private static final Hungry hungry = new Hungry();

    public static Hungry getInstance(){

        return  hungry;
    }

}

懒汉模式

 //在外部需要使用的时候才进行实例化
public class LazyOne {
    private LazyOne(){}


    //静态块,公共内存区域
    private static LazyOne lazy = null;

    public static LazyOne getInstance(){

        //调用方法之前,先判断
        //如果没有初始化,将其进行初始化,并且赋值
        //将该实例缓存好
        if(lazy == null){
            lazy = new LazyOne();
        }
        //如果已经初始化,直接返回之前已经保存好的结果

        return lazy;

    }

}

静态内部类

public class LazyThree {

    //默认使用LazyThree的时候,会先初始化内部类
    //如果没使用的话,内部类是不加载的

    private LazyThree(){}

    //static 是为了使单例的空间共享
    //保证这个方法不会被重写,重载
    public static final LazyThree getInstance(){
        //在返回结果以前,一定会先加载内部类
        return LazyHolder.LAZY;
    }


    //默认不加载
    private static class LazyHolder{
        private static final LazyThree LAZY = new LazyThree();
    }


}

注册登记模式

//注册式单例
public class RegisterMap_bxc {
    //相当于本地缓存
    private static Map<String,Object> regist = new HashMap<String,Object>();

    public static RegisterMap_bxc getInstance(String name)
    {
        if(null == name)
        {
            name = RegisterMap_bxc.class.getName();
        }
        synchronized (regist)
        {
            if(!regist.containsKey(name))
            {
                regist.put(RegisterMap_bxc.class.getName(),new RegisterMap_bxc());
            }
            return (RegisterMap_bxc)regist.get(name);
        }

    }

}

总结

饿汉模式:

优点:饿汉模式是线程安全的,而且执行效率比较高,从用户的体验来说比懒汉好

缺点:因为它在类加载的时候就初始化了,不管是否用到,所以饿汉模式浪费系统资源

懒汉模式:

优点:在类加载的时候不会初始化,只有当调用的时候才会初始化,所以比较节约资源

缺点:线程不安全,高并发的情况下容易出错

静态内部类:

可以说静态内部类综合了懒汉和饿汉模式,在外部类调用的时候,内部类才会被初始化,而且避免了线程安全性的问题

注册登记模式:

spring中就是用这种方法来管理实例的,目前对源码还在研究中,这里就不多说了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 并发编程的基础

      对于并发编程这块知识点的掌控一直不是很好,基本都是停留在使用synchronized阶段,于是决定开一博客专题记录知识点。

    会说话的丶猫
  • HashMap中add()方法的源码学习

    HashMap中实际是维护了一个Node数组,用来存储数据,下面看一下Node源码:

    会说话的丶猫
  • 线程池的实现原理分析

    在 Java 中,如果每个请求到达就创建一个新线程,创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。如果...

    会说话的丶猫
  • 猿思考系列3——一文搞懂单例和思考的套路

    看完上一个章节,相信你已经掌握了一些编写并发代码编写的要领了。今天我们来聊一个新的话题。有童鞋反映说之前的两篇思考,内容有些深了,不是太好理解,猿人工厂君决定调...

    山旮旯的胖子
  • 猿思考系列3——一文学会思考的正确姿势

    看完上一个章节,相信你已经掌握了一些编写并发代码编写的要领了。今天我们来聊一个新的话题。有童鞋反映说之前的两篇思考,内容有些深了,不是太好理解,猿人工厂君决定调...

    山旮旯的胖子
  • ES6 系列之私有变量的实现

    在阅读 《ECMAScript 6 入门》的时候,零散的看到有私有变量的实现,所以在此总结一篇。

    腾讯NEXT学位
  • Java_基础_01_static和final

    shirayner
  • 专访 | 谷歌无人车之父 Sebastian Thrun:技术赋予我们超人力量

    【新智元导读】Sebastian Thrun是斯坦福大学终身教授,人工智能领域专家,2007年加入谷歌,领导了谷歌街景的研究,后来创建了Google X 实验室...

    新智元
  • SpringBoot 利用 AOP 记录日志

    Aspect Oriented Programming 面向切面编程。解耦是程序员编码开发过程中一直追求的。AOP也是为了解耦所诞生。

    JAVA日知录
  • 请不要再使用判断进行参数校验了

    因为网络传输的不可靠性,以及前端数据控制的可篡改性,后端的参数校验是必须的,应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。

    码农小胖哥

扫码关注云+社区

领取腾讯云代金券