浅谈设计模式 - 单例模式(一)(上)

简介: 浅谈设计模式 - 单例模式(一)(上)

什么是单例模式?



网络异常,图片无法展示
|


介绍


保证一个类仅有一个实例,并提供一个全局访问点


单例模式的几个应用场景


  1. SpringBean 默认就是单例的,不过用的是动态代理生成代理对象
  2. 工具类里面,由一个单例保存
  3. 其他需要唯一对象的场景


如何实现单例模式


饿汉式



解释:和名字一般,很饿,所以在使用之前就做好了准备


优点:


  1. 保证单例对象不会重复
  2. 永远不会有重复创建的隐患


缺点:


  1. 如果对象较大比较占用jvm内存空间
  2. 影响性能,带来没有必要的对象创建。


实现代码:


/**
 *
 * 单例模式 - 饿汉式
 * @author zhaoxudong
 * @version 1.0
 * @date 2020/10/27 21:45
 */
public class Hungry {
    private static final Hungry instance = new Hungry();
    public static Hungry getInstance(){
        return instance;
    }
    public static void main(String[] args) {
        Hungry instance = Hungry.getInstance();
        System.err.println(instance);
    }
}
复制代码


非常简单,在创建之前,旧对对象进行了初始化,其实对于比较小的对象,这种方式在实际的使用过程中最多


懒汉式



解释:犹如一个懒汉,只有在使用到的时候,才进行初始化。


优点:


  1. 可以节省系统资源只有真正使用的时候,才会进行获取
  2. 对于


缺点:


  1. 如果多线程并发访问会出现多次实例化的问题


实现代码:


package com.zxd.interview.desginpattern.single;
import com.zxd.interview.util.ExecuteUtil;
/**
 * 单例模式 - 懒汉式
 *
 * @author zhaoxudong
 * @version 1.0
 * @date 2020/10/27 21:45
 */
public class Lazy {
    public static void main(String[] args) {
        // 常规多线程
//        for (int i = 0; i < 100; i++) {
//            new TestRunThread().start();
//        }
        try {
            ExecuteUtil.startTaskAllInOnce(50000, new TestRunThread());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 模拟异步请求
 * 模拟十组数据
 */
class TestRunThread extends Thread {
    @Override
    public void run() {
        // 懒汉式第一版
//        int i = LazyVersion1.getInstance().hashCode();
        // 懒汉式第二版
//        int i = LazyVersion2.getInstance1().hashCode();
        // 懒汉式第三版
        int i = LazyVersion2.getInstance2().hashCode();
        System.err.println(i);
    }
}
/**
 * 饿汉式的第一版本
 */
class LazyVersion1 {
    private static LazyVersion1 lazyVersion1;
    public static LazyVersion1 getInstance() {
        if (lazyVersion1 == null) {
            // 验证是否创建多个对象
            try {
                // 模拟在创建对象之前做一些准备工作
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lazyVersion1 = new LazyVersion1();
        }
        return lazyVersion1;
    }
}
/**
 * 懒汉式的第二版本
 * 1. 直接对整个方法加锁
 * 2. 在局部代码块加锁
 */
class LazyVersion2 {
    /**
      非常重要的点: volatile 避免cpu指令重排序
    */
    private static volatile LazyVersion2 lazyVersion2;
    /**
     * 在方法的整体加入 synchronized
     *
     * @return
     */
    public synchronized static LazyVersion2 getInstance1() {
        if (lazyVersion2 == null) {
            // 验证是否创建多个对象
            try {
                // 模拟在创建对象之前做一些准备工作
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lazyVersion2 = new LazyVersion2();
        }
        return lazyVersion2;
    }
    /**
     * 在局部代码快加入 synchronized
     *
     * @return
     */
    public static LazyVersion2 getInstance2() {
        if (lazyVersion2 == null) {
            // 验证是否创建多个对象
            try {
                // 模拟在创建对象之前做一些准备工作
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (LazyVersion2.class) {
                if (lazyVersion2 == null) {
                    lazyVersion2 = new LazyVersion2();
                }
            }
        }
        return lazyVersion2;
    }
}
复制代码


注意点:


  1. volatile 关键字是JDK1.5之后的JMM为了防止CPU指令重排序的问题而加入的一种具体机制
  2. 虽然发生的几率非常小的,但是指令重排序是JVM的本身特点


private static volatile LazyVersion2 lazyVersion2;
复制代码


目录
打赏
0
0
0
0
4
分享
相关文章
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
35 2
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
29 2
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
48 4
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
29 1
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
33 0
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和复用性的关键技术之一。本文将通过探讨单例模式,一种最常用的设计模式,来揭示其在PHP中的应用及优势。单例模式确保一个类仅有一个实例,并提供一个全局访问点。通过实际案例,我们将展示如何在PHP项目中有效实现单例模式,以及如何利用这一模式优化资源配置和管理。无论是PHP初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和技巧,进而提升自己的编程实践。
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy&lt;T&gt;` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
106 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等