单例模式的四种创建方式

这篇具有很好参考价值的文章主要介绍了单例模式的四种创建方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

单例模式是日常开发中最常见的一种设计模式,常用来做为池对象,或者计数器之类的需要保证全局唯一的场景。

单例模式的目的是保证在整个程序中只存在一个对象实例,使用单例一个前提条件就是构造器私有化,不允许通过new 对象的方式。单例模式的实现主要方式有如下几种:
1、饿汉式实现
2、使用枚举类实现
3、懒汉式使用双重检查锁实现。
4、使用静态内部类实现

“饿汉式”

饿汉式:顾名思义就是很"饥饿",初始化就创建设好了实例。

public class Demo1 {

    private static Demo1 demo1 = new Demo1();

    private void Demo1() {

    }

    public static Demo1 getInstance() {

        return demo1;
    }
}

“懒汉式” -双重检查锁

为什么要使用双重检查锁?因为如果在并发的状态下,如果A线程先进来,判断demo2为null,然后创建实例对象,在判断了为null的这个时间点,B线程也进来了判断demo2为null,也去创建实例,这样就不能保证单例。

public class Demo2 {

    private volatile static Demo2 demo2 = null;

    private void Demo2() {

    }

    public static Demo2 getInstance() {

        if (demo2 == null) {

            synchronized(Demo2.class) {
                if (demo2 == null) {
                    demo2 = new Demo2();
                }
            }
        }

        return demo2;
    }

}

“懒汉式” -使用静态内部类的方式实现

使用静态内部类的方式实现的单例式利用了java的特性,就是static属于类,在初始化的时候就已经执行了,且static修饰的对象或者静态代码块只执行一次。

public class Demo3 {

    private static Demo3 demo3;

    private void Demo3() {

    }

    private static class HolderClass {
        private static Demo3 demo3 = new Demo3();
    }

    public static Demo3 getInstance() {

        return HolderClass.demo3;
    }
}

枚举方式

枚举方式利用了枚举的特性,enum修饰的类被称之为枚举类,java不允许通过反射来创建enum类,同时enum修饰的类默认继承了Enum类,其构造函数为private修饰的,因此枚举类具有天然的单例特性,很适合用做单例模式。

public class Demo4 {

    private Demo4() {

    }

    public static enum SingleEnum {

        INSTANCE;

        private Demo4 demo4;

        private SingleEnum() {
            demo4 = new Demo4();
        }

        public Demo4 getInstance() {
            return demo4;
        }
    }

    public static Demo4 getInstance() {
        return SingleEnum.INSTANCE.getInstance();
    }

    // 测试
    public static void main(String[] args) {
        Demo4 instance = getInstance();

    }
}

下面来看一个单例模式的典型应用场景:
JefLogTail采集工具中的server端,在处理日志多线程入库时,为了防止反复的创建线程池导致服务器压力大,因此采用单例模式来定义线程池的获取。如下:文章来源地址https://www.toymoban.com/news/detail-430186.html

public class LogHandle extends ServerMessageHandler {

    private LogSave logSave;
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Message message) throws Exception {
       try {
/*           String content = (String) message.getContent();
           String ip = message.getAttachment("ip");
           String fileName = message.getAttachment("fileName");
           System.out.println("ip地址:" + ip);
           System.out.println("文件名称:" + fileName);*/
           ThreadPoolCfg.getThreadPool().execute(new Runnable() {
               @Override
               public void run() {
                   logSave.save(message);
               }
           });
           // 多线程处理
       } catch (Exception e) {
           e.printStackTrace();
       }
    }

    public void setLogSavePlan(LogSave logSave) {
        this.logSave = logSave;
    }
}

到了这里,关于单例模式的四种创建方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 创建单例模式的7种方式

    想要了解更多知识或者需要源码学习小程序搜索:源码轻舟 饿汉式 懒汉式 双重监测 静态内部类(推荐) 枚举(推荐) 多例模式 线程唯一

    2024年02月12日
    浏览(22)
  • 7种创建方式,带你理解Java的单例模式

    本文分享自华为云社区《《Java极简设计模式》第01章:单例模式(Singleton)》,作者:冰 河。 看几个单例对象的示例代码,其中有些代码是线程安全的,有些则不是线程安全的,需要大家细细品味,这些代码也是在高并发环境下测试验证过的。 代码一:SingletonExample1 这个类

    2024年02月12日
    浏览(41)
  • View 的四种 OnClick 方式

    嗨喽,大家好!今天呢,我跟大家聊一聊Android 的View 的点击事件onClick 。额,有点拗口(^_^) 。 看过我的文章的人可能会好奇,你怎么写Android的文章了啊?说起这啊,就是我的血泪史了,此处省略一万字.................... 废话不多说,让我们代码走起,风里来,雨里去,唯有代

    2023年04月15日
    浏览(41)
  • JavaScript中的四种枚举方式

    字符串和数字具有无数个值,而其他类型如布尔值则是有限的集合。 一周的日子(星期一,星期二,...,星期日),一年的季节(冬季,春季,夏季,秋季)和基本方向(北,东,南,西)都是具有有限值集合的例子。 当一个变量有一个来自有限的预定义常量的值时,使用

    2024年02月03日
    浏览(56)
  • STM32的四种开发方式

    首先看下ST官方给出的四种开发方式的比较 寄存器开发 寄存器编程对于从51等等芯片过渡过来的小伙伴并不陌生,不管你是什么库,最终操作的还是寄存器,所以对于标准库、HAL库、LL库都是在寄存器上的编程,所以可以直接在各种库中直接操作寄存器。 但寄存器开发方法到

    2024年02月11日
    浏览(41)
  • CSS中的四种定位方式

    在CSS中定位有以下4种: 静态定位 - static 相对定位 - relative 绝对定位 - absolute 固定定位 - fixed 静态定位是css中的默认定位方式,也就是没有定位。在此定位方式中设置:top,bottom,left,right,z-index 这些属性都是无效的。 相对位置前的位置: 相对位置后的位置: 可以看到该

    2024年02月08日
    浏览(85)
  • python导入库的四种方式

    目录 前言 一、import 库名 二、import 库名 as 别名(变量名) 三、from 库名 import 方法名 四、from 库名 import* 库可以抽象的理解为一个工具包,而库里的方法可以理解为工具包里各式各样的工具,每个工具作用不同。 此文例子库名为pygame,也就是工具包的名字,例子方法为ini

    2024年02月05日
    浏览(36)
  • C++文件读取的四种方式

    C++可以根据不同的目的来选取文件的读取方式,目前为止学习了C++中的四种文件读取方式。 C++文件读取的一般步骤: 1、包含头文件 #includefstream 2、创建流对象:ifstream ifs (这里的ifs是自己起的流对象名字) 3、打开文件:file.open(\\\"文件路径\\\",\\\"打开方式\\\"),打开文件后并判断文件是

    2024年02月11日
    浏览(40)
  • SpringBoot导出Excel的四种方式

           近期接到了一个小需求,要将系统中的数据导出为Excel,且能将Excel数据导入到系统。对于大多数研发人员来说,这算是一个最基本的操作了。但是……我居然有点方!         好多年没有实操这种基础的功能了。我对于excel导入导出的印象还停留在才入行时的工作经

    2024年02月03日
    浏览(41)
  • 记录-实现深拷贝的四种方式

    深拷贝:在堆内存中重新开辟一个存储空间,完全克隆一个一模一样的对象 浅拷贝:不在堆内存中重新开辟空间,只复制栈内存中的引用地址。本质上两个对象(数组)依然指向同一块存储空间 使用递归的方式进行对象(数组)的深拷贝 奉上已封装的深拷贝函数👇 上方函

    2023年04月21日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包