设计模式学习05----之单例模式

简介: 单例模式,是我们最常用也最熟悉的一种设计模式,其使用要注意线程安全。

单例模式,是我们最常用也最熟悉的一种设计模式,其使用要注意线程安全。


定义

单例模式:顾名思义,就是在应用中有且只有一个实例。一般类似于计数器类的都必须是单例,多例会导致计数结果不准。

一般而言,其分为饿汉式和懒汉式。


懒汉式

懒汉式:顾名思义,就是不在系统加载时创建类的实例。而是在调用时才去一次性创建。

demo如下:

package com.singleton;
/**
 * 懒汉式
 * @author xiang.wei
 */
public class LazySingleton {
  /**
  * 定义一个私有变量,目的是外部不能直接访问该变量,必须通过公共的访问方法来访问
  */
  private static LazySingleton instance=null;
  /**
  * 私有化构造器,使之不能直接构造对象
  */
  private LazySingleton(){
  }
  /**
  * 公共的提取对象的方法
  * @return
  */
  public synchronized static LazySingleton getInstance() {
     if (instance==null) {
             instance=new LazySingleton();
        }
     return instance;
  }
}


饿汉式

饿汉式:与懒汉式相反,饿汉式就是在系统加载时就去创建类的实例。

demo如下:

package com.singleton;
/**
 * 饿汉式
 * @author xiang.wei
 * @create 2018/4/10 10:34
 */
public class HungrySingleton {
    private static final HungrySingleton SINGLETON = new HungrySingleton();
    private HungrySingleton() {
    }
    public static HungrySingleton getInstance() {
        return SINGLETON;
    }
}


总结:饿汉式与懒汉式相比要占用更多的内存,因为系统加载之后就会创建实例。但是效率要比懒汉式要高。


双重加锁

双重加锁是懒汉式的一种扩展。因为直接在getInstance()上加上synchronized会导致每次调用方法时都需要加锁。执行效率不高。所以,我们采用了双重加锁的方式。

package com.singleton;
/**
 * 懒汉式
 * 双重加锁
 * @author xiang.wei
 */
public class LazySingleton_two {
    /**
     * 定义一个私有变量,目的是外部不能直接访问该变量,必须通过公共的访问方法来访问
     */
    private static  volatile LazySingleton_two instance = null;
    /**
     * 私有化构造器,使之不能直接构造对象
     */
    private LazySingleton_two() {
    }
    /**
     * 公共的提取对象的方法
     *
     * @return
     */
    public static LazySingleton_two getInstance() {
        //如果单例存在则直接返回
        if (instance == null) {
            //单例不存在,则进入同步代码块
            synchronized (LazySingleton_two.class) {
                if (instance == null) {
                    System.out.println("实例化的次数");
                    instance = new LazySingleton_two();
                }
            }
        }
        return instance;
    }
}


双重加锁并不是加两个synchronized关键字。

第一个判断是当对象存在时则直接返回实例,当对象不存在时则进入同步代码块中,同步代码块的作用跟之前是相同的,就是防止两个线程同时访问同步代码块的内容,造成生成多个实例的情况。同步代码块每次只允许一个线程进入,创建完实例后返回。第二个判断是当多个线程排队进入代码块时,第一个线程创建完实例返回后,第二个线程再进入时,不需要在创建实例。

采用双重加锁后,代码的执行效率有了较大的提升。


静态内部类的方式

public class MySingleton {
    private static class MySingletonHandle {
        private static final MySingleton instance = new MySingleton();
    }
    private MySingleton() {
    }
    public MySingleton getSingleton() {
        return MySingletonHandle.instance;
    }
}


注:Spring 容器中所有的Bean都是单例的


代码请见:

https://github.com/XWxiaowei/JavaCode/tree/master/design-patterns


参考

https://www.cnblogs.com/V1haoge/p/6510196.html


相关文章
|
设计模式 缓存 安全
【设计模式】【创建型模式】单例模式(Singleton)
一、入门 什么是单例模式? 单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。它常用于需要全局唯一对象的场景,如配置管理、连接池等。 为什么要单例模式? 节省资源 场景:某些对象创
482 15
|
设计模式 安全 Java
设计模式:单例模式
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。它通过私有化构造函数、自行创建实例和静态方法(如`getInstance()`)实现。适用于数据库连接池、日志管理器等需要全局唯一对象的场景。常见的实现方式包括饿汉式、懒汉式、双重检查锁、静态内部类和枚举。线程安全问题可通过`synchronized`或双重检查锁解决,同时需防止反射和序列化破坏单例。优点是避免资源浪费,缺点是可能增加代码耦合度和测试难度。实际开发中应优先选择枚举或静态内部类,避免滥用单例,并结合依赖注入框架优化使用。
|
设计模式 存储 安全
设计模式2:单例模式
单例模式是一种创建型模式,确保一个类只有一个实例,并提供全局访问点。分为懒汉式和饿汉式: - **懒汉式**:延迟加载,首次调用时创建实例,线程安全通过双重检查锁(double check locking)实现,使用`volatile`防止指令重排序。 - **饿汉式**:类加载时即创建实例,线程安全但可能浪费内存。 示例代码展示了如何使用Java实现这两种模式。
355 4
|
设计模式 存储 安全
设计模式-单例模式练习
单例模式是Java设计模式中的重要概念,确保一个类只有一个实例并提供全局访问点。本文详解单例模式的核心思想、实现方式及线程安全问题,包括基础实现(双重检查锁)、懒汉式与饿汉式对比,以及枚举实现的优势。通过代码示例和类图,深入探讨不同场景下的单例应用,如线程安全、防止反射攻击和序列化破坏等,展示枚举实现的简洁与可靠性。
249 0
|
设计模式 存储 前端开发
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
723 13
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
253 2
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
282 4
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
163 0