首页 > 其他分享 >学习笔记-设计模式-创建型模式-单例模式

学习笔记-设计模式-创建型模式-单例模式

时间:2023-10-09 11:55:05浏览次数:37  
标签:Singleton 模式 instance 线程 private 单例 static 设计模式 public

单例模式

一个类只有一个实例,并提供一个全局访问此实例的点,哪怕多线程同时访问。

单例模式主要解决了一个全局使用的类被频繁的创建和消费的问题。

单例模式的案例场景

  • 数据库的连接池不会反复创建
  • spring中一个单例模式bean的生成和使用
  • 在我们平常的代码中需要设置全局的一些属性保存

七种单例模式的实现

1.懒汉模式(线程不安全,懒加载)
public static class Singleton_01 {
    private static Singleton_01 instance;
    
    private Singleton_01() {}
    
    public static Singleton_01 getInstance() {
        if (null != instance) {
            return instance;
        }
        instance = new Singleton_01();
        return instance;
    }
}

非常标准且简单地单例模式。

满足了懒加载,但是线程不安全。

2.懒汉模式(线程安全,懒加载)
public static class Singleton_02 {
    private static Singleton_02 instance;
    
    private Singleton_02() {}
    
    public static synchronized Singleton_02 getInstance() {
        if (null != instance) {
            return instance;
        }
        instance = new Singleton_02();
        return instance;
    }
}

线程安全,但是效率低,不建议使用。

3.饿汉模式(线程安全)
public class Singleton_03 {
    private static Singleton_03 instance = new Singleton_03();
    
    private Singleton_03() { }
    
    public static Singleton_03 getInstance() {
        return instance;
    }   
}

饿汉模式,在程序启动的时候直接运行加载。

4.使用内部静态类(线程安全、懒加载)
public class Singleton_04 {
    private static class SingletonHolder {
        private static Singleton_04 instance = new Singleton_04();
    }
    
    private Singleton_04() { }
    
    public static Singleton_04 getInstance() {
        return SingletonHolder.instance;
    }
}

通过内部静态类实现了懒加载和线程安全,推荐使用。

5.锁+双重校验(线程安全,懒加载)
private class Singleton_05 {
    private static volatile Singleton_05 instance;
    
    private Singleton_05() { }
    
    public static Singleton_05 getInstance() {
        if (null != instance) {
            return instance;
        }
        synchronized (Singleton_05.class) {
            if (null == instance) {
                instance = new Singleton_05();
            }
        }
        return instance;
    }
}

相较于线程安全的懒汉模式,这种方法效率更高。

6.CAS【AtomicReference】(懒加载,线程安全)
public class Singleton_06 {
    private static final AtomicReference<Singleton_06> INSTANCE = new AtomicReference<Singleton_06>();
    
    private Singleton_06() {  }
    
    public static final Singleton_06 getInstance() {
        for(;;) {
            Singleton_06 instance = INSTANCE.get();
            if (null != instance) {
                return instance;
            }
            INSTANCE.compareAndSet(null, new Singleton_06());
            return INSTANCE.get();
        }
    }
}

AtomicReference<V>可以封装引用一个V实例,支持并发访问。

使用CAS的好处就是不需要使用传统的加锁方式保证线程安全,而是依赖于CAS的忙等算法,依赖于底层硬件的实现,来保证线程安全。相对于其他锁的实现,没有线程的切换和阻塞,也就没有了额外的开销,并且可以迟迟较大的并发性。

但CAS的一个缺点就是忙等,如果一直没有获取到将会处于死循环中。

7.枚举单例(线程安全)
public enum Singleton_07 {
    
    INSTANCE;
    
    private Map<String, String> cache = new ConcurrentHashMap<>();

    public Map<String, String> getCache() {
        return cache;
    }

    public void addToCache(String key, String value) {
        cache.put(key, value);
    }
}

《Effective Java》作者推荐使用枚举的方式解决单例模式,这种方法解决了线程安全、自由串行化和单一实例的问题。

调用时也很方便:Singleton_07.INSTANCE.getCache();

枚举单例十分简洁,并且它无常地提供了串行化机制,绝对防止对此实例化(毕竟是枚举)。

但是它在继承的场景下是不可使用的,并且不是懒加载(毕竟是枚举)。

标签:Singleton,模式,instance,线程,private,单例,static,设计模式,public
From: https://www.cnblogs.com/Andl-Liu/p/17751393.html

相关文章

  • Java设计模式之建造者模式
    1.1.概述将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。• 分离了部件的构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。• 由于实现了构建和装配的解耦。不同的构建器,相......
  • 设计模式 (1): 5 种创建型模式 (结合代码详解)
    目录1单例模式饿汉单例懒汉单例双重检验单例静态内部类单例破坏单例(反射、反序列化)枚举类单例2工厂模式简单工厂模式工厂方法模式3抽象工厂模式代码实现对比三种工厂模式如何选择工厂方法和抽象工厂?4建造者模式5原型模式1单例模式需考虑的问题:是否线程安全是否延......
  • 华为跟思科配置VLAN与trunk模式切换
    华为交换机跟思科交换机设置VLAN跟trunk与access模式切换在原有交换机基础上配上vlan,vlan是一种隔离技术1.隔离广播   2.隔离故障配置交换机(华为)1. sy回车,进入配置模式undo in en   关闭英文提示,好看一点,可以不打。实际工作中,不打。2. 分别输入vlan10 ......
  • 【愚公系列】2023年10月 二十三种设计模式(七)-桥接模式(Bridge Pattern)
    ......
  • 456. 132模式
    链接https://leetcode.cn/problems/132-pattern/description/思路这题其实不难,就是边界条件难想。我们可以先保证单调栈里是逆序,然后判断单调栈中较小的值是否大于当前元素(满足132的1和2的关系)。代码classSolution:deffind132pattern(self,nums)->bool:......
  • node-oracledb nodejs 包支持thin 模式了
    node-oracledb从v6.0.0版本来时支持thin模式了,是基于纯javascript开发的驱动,我们终于可以不用依赖比较笨重的oracleclient了属于一个很大的进度,同时python版本也是支持thin模式了,我以前也简单介绍过参考资料https://github.com/oracle/node-oracledb/releaseshttps://me......
  • Zabbix-agent修改为主动模式
    1.zabbix-agent工作模式zabbix-agent进程,有两种工作模式,主动模式,被动模式1.1被动模式被动模式是指zabbix-server将需要请求的数据,发给zabbix-agent,然后agent接收到请求后才进行对客户端机器数据采集,采集完毕后发给zabbix-server,交给zabbix-UI展示。但是这个过程是一次一......
  • 【WPF】单例软件实现自重启
    原文地址https://www.cnblogs.com/younShieh/p/17749694.html❤如果本文对你有所帮助,不妨点个关注和推荐呀,这是对笔者最大的支持~❤ 在WPF应用程序中,想要实现软件重启,可以再Start一次该软件的exe程序。但是有些时候我们想要这个程序是唯一运行的单例,而不是可以多开的程序。......
  • 0.MVC模式概述
    MVC模式Model、View、Controller。是一种设计规范,目的是降低业务逻辑之间的耦合。1、Model模型DAO、Service,负责模型数据操作,包括了数据和业务。2、View视图负责模型的展示,用户客户看得到的界面。3、Controller控制器接收请求,发送给model进行处理,模型处理完后接收模型返回......
  • Java设计模式之享元模式
    1.1.概述定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销,从而提高系统资源的利用率。 1.2.结构享元(Flyweight)模式中存在以下两种状态:1.内部状态,即不会随着环境的改变而改变的可......