Java中常用的设计模式之单例模式详解

目录
  • 注意
  • 优点
  • 缺点
  • 使用场景
    • 一、实现方式
    • 二、实现方式
    • 三、测试
  • 总结

注意

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

优点

1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。

2.避免对资源的多重占用(比如写文件操作)。

缺点

1.没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

使用场景

1.要求生产唯一序列号。

2.WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。

3.创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

一、实现方式

package com.asurplus.common.singleton.style1;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
@Slf4j
public class ResUtils {
    private volatile static ResUtils instance = null;
    /**
     * 私有的构造方法
     */
    private ResUtils() {
    }
    /**
     * 提供获取实例的方法
     *
     * @return
     */
    public static ResUtils getInstance() {
        // 为空才创建
        if (Objects.isNull(instance)) {
            // 避免并发操作时
            synchronized (ResUtils.class) {
                // 为空才创建
                if (Objects.isNull(instance)) {
                    // 创建新对象
                    instance = new ResUtils();
                    log.info("创建了对象");
                }
            }
        }
        return instance;
    }
}

我们将其构造方法私有化,从而外部无法创建实例,并且我们提供了获取唯一实例的方法,这样我们就能从外部得到该实例。

二、实现方式

package com.asurplus.common.singleton.style2;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ResUtils2 {
    /**
     * 静态内部类
     */
    private static class ResUtils2Holder {
        private static ResUtils2 instance = new ResUtils2();
    }
    /**
     * 提供获取实例的方法
     *
     * @return
     */
    public static ResUtils2 getInstance() {
        return ResUtils2Holder.instance;
    }
}

我们使用静态内部类的方法创建实例,因为 JVM 只会加载一次的原理,所以最终只会创建一个实例,并且提供了获取实例的方法,这样我们就能从外部得到该实例。

三、测试

package com.asurplus.common.singleton;
import com.asurplus.common.singleton.style1.ResUtils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * 单例模式
 */
public class TestMain {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            executorService.execute(ResUtils::getInstance);
        }
        executorService.shutdown();
    }
}

输出结果

可以看出,我们获取了 100 次实例,只创建了一个实例,从而实现了我们的单例模式。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • java编程创建型设计模式单例模式的七种示例

    目录 1.什么是单例模式? 2.七种写法 2.1饿汉式(静态常量) 2.2饿汉式(静态代码块) 2.3懒汉式(线程不安全) 2.4懒汉式(线程安全,同步方法) 2.5双重校验锁 2.6静态内部类 2.7枚举 3.单例模式在JDK中的应用(简单的源码分析) 4.单例模式总结 1.什么是单例模式? 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法). 比如Hibernate的 SessionFactory,

  • Java23种设计模式中的单例模式你了解吗

    目录 1.定义 2.适用场景 3.常见写法 4.如何防止单例被破坏 1.多线程破坏单例以及解决方法 2.反射破坏单例以及解决方法 3.序列化破坏单例以及解决方法 5.优缺点 6.总结 1.定义 单例模式(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.隐藏其所有的构造方法.属于创建型模式. 2.适用场景 确保任何情况下都绝对只有一个实例. 3.常见写法 第一种:饿汉式单例:在单例类首次加载时就创建实例 /** * @Package: com

  • Java设计模式之单例模式示例详解

    目录 0.概述 1.饿汉式 1.1 饿汉式单例实现 1.2 破坏单例的几种情况 1.3 预防单例的破坏 2.枚举饿汉式 2.1 枚举单例实现 2.2 破坏单例 3.懒汉式 4.双检锁懒汉式 5.内部类懒汉式 6.JDK中单例的体现 0.概述 为什么要使用单例模式? 在我们的系统中,有一些对象其实我们只需要一个,比如说:线程池.缓存.对话框.注册表.日志对象.充当打印机.显卡等设备驱动程序的对象.事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常.

  • 深入理解Java设计模式之单例模式

    目录 一.什么是单例模式 二.单例模式的应用场景 三.单例模式的优缺点 四.单例模式的实现 1.饿汉式 2.懒汉式 3.双重加锁机制 4.静态初始化 五.总结 一.什么是单例模式 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在. 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息.这种方式简

  • JAVA设计模式零基础解析之单例模式的八种方式

    目录 单例模式简介: 单例模式优点: 应用场景: 单例设计模式的八种方式: 1.饿汉式(静态常量) 2.饿汉式(静态代码块) 3.懒汉式(线程不安全) 4.懒汉式(线程安全,同步方法) 5.懒汉式(线程安全,同步代码块) 6.双重检查(推荐使用) 7.静态内部类(推荐使用) 8.枚举(推荐使用) 单例模式在JDK应用的源码分析 单例模式注意事项和细节说明 单例模式简介: 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了

  • Java中常用的设计模式之单例模式详解

    目录 注意 优点 缺点 使用场景 一.实现方式 二.实现方式 三.测试 总结 注意 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 优点 1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存). 2.避免对资源的多重占用(比如写文件操作). 缺点 1.没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化. 使用场景 1.要求生产唯一序列号. 2.WE

  • Java中常用的设计模式之观察者模式详解

    目录 优点 缺点 使用场景 注意事项 一.实现方式 1.观察者抽象类 2.第一个观察者 3.第二个观察者 4.第三个观察者 5.定义主题 二.测试 总结 优点 1.观察者和被观察者是抽象耦合的. 2.建立一套触发机制. 缺点 1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间. 2.如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃. 3.观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而

  • JAVA中常用的设计模式:单例模式,工厂模式,观察者模式

    1.单例模式 每个类只能创建一个实例对象 Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection). 好处: 第一.控制资源的使用,通过线程同步来控制资源的并发访问: 第二.控制实例产生的数量,达到节约资源的目的. 第三.作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程

  • Java中常用的日期类图文详解

    目录 前言 Date 为什么Date的大部分方法被弃用 注释 翻译 目前可用方法的测试示例 可用方法 示例 Date小结 Calendar 简单介绍 常用的方法 获取实例 获取日期里的信息 日期的加减与滚动 日期的设置 测试实例代码 DateFormat与SimpleDateFormat DateFormat 常用方法 测试实例 SimpleDateFormat 主要方法 测试示例 编写一个简单的日期工具类 工具类 测试示例 总结 前言 本文将分析Java中的Date.Calendar.Date

  • java中Executor,ExecutorService,ThreadPoolExecutor详解

    java中Executor,ExecutorService,ThreadPoolExecutor详解 1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thre

  • Java中Properties类的操作实例详解

    Java中Properties类的操作实例详解 知识学而不用,就等于没用,到真正用到的时候还得重新再学.最近在看几款开源模拟器的源码,里面涉及到了很多关于Properties类的引用,由于Java已经好久没用了,而这些模拟器大多用Java来写,外加一些脚本语言Python,Perl之类的,不得已,又得重新拾起.本文通过看<Java编程思想>和一些网友的博客总结而来,只为简单介绍Properties类的相关操作.  一.Java Properties类 Java中有个比较重要的类Properti

  • Java动态代理(设计模式)代码详解

    基础:需要具备面向对象设计思想,多态的思想,反射的思想: Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对Java动态代理机制有更加深入的理解.本文首先从Java动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理模

  • Java中接口和抽象类的区别详解

    需求:接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承实体类(concrete class)?抽象类中是否可以有静态的main方法? 先说明二者的定义,然后聊聊需求,最后分析二者的区别. 含有abstract修饰符的类即为抽象类,抽象类不能创建实例对象.含有抽象方法的类必须定义为abstract class.在abstract class中,方法不必是抽象的,但是抽象方法必须在具体子类中实现,所以,不能有抽象构造方法或抽象静态方法.子类如果没有实现抽象父类中的所

  • SpringMVC中常用注解与使用方法详解

    MVC简介 MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写, 是一种用于设计创建 Web 应用程序表现层的模式. Model(模型): 通常指的就是我们的数据模型.作用一般情况下用于封装数据. View(视图): 通常指的就是我们的 jsp 或者 html.作用一般就是展示数据的. 通常视图是依据模型数据创建的. Controller(控制器): 是应用程序中处理用户交互的部分.作用一般就是处理程序逻辑的.

  • Java 中泛型 T 和 ? 的区别详解

    目录 泛型中 T 类型变量 和 ? 通配符 区别 Generic Types 类型变量 用法 2.声明通用的方法 – 泛型方法: 有界类型参数 Wildcards 通配符 1.上界通配符:? extend 上界类型 2.无界通配符:? 3.下界通配符:? super 子类 类型擦除 泛型中 T 类型变量 和 ? 通配符 区别 定义不同 :T 是类型变量,? 是通配符 使用范围不同: ? 通配符用作 参数类型.字段类型.局部变量类型,有时作为返回类型(但请避免这样做) T 用作 声明类的类型参数.

随机推荐