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

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

什么是单例模式?



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


介绍


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


单例模式的几个应用场景


  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;
复制代码


相关文章
|
12天前
|
设计模式 安全 Java
【设计模式系列笔记】单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点,以便全局范围内访问这个实例。单例模式的目标是限制一个类的实例化,确保在整个应用程序中只有一个实例存在,并提供对这个唯一实例的全局访问点。这对于控制对资源的访问、限制特定类的实例数量等场景非常有用。
121 5
|
2月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
62 0
|
2月前
|
设计模式 缓存 安全
【设计模式】单例模式:确保类只有一个实例
【设计模式】单例模式:确保类只有一个实例
23 0
|
23天前
|
设计模式 PHP
php设计模式--单例模式(三)
php设计模式--单例模式(三)
12 0
|
5天前
|
设计模式 安全 Java
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
|
4月前
|
设计模式 安全 Java
设计模式-单例模式
设计模式-单例模式
38 0
|
2月前
|
设计模式 安全 Java
设计模式之单例模式
设计模式之单例模式
|
3天前
|
设计模式 安全 Java
【设计模式学习】单例模式和工厂模式
【设计模式学习】单例模式和工厂模式
|
3天前
|
设计模式 安全 Java
|
5天前
|
设计模式 存储 安全
Java 设计模式:深入单例模式的理解与应用
【4月更文挑战第27天】单例模式是一种常用的设计模式,在 Java 开发中扮演着重要角色。此模式的主要目的是保证一个类只有一个实例,并提供一个全局访问点。
13 0