Design Pattern 1: Singleton

本文详细介绍了单例模式的实现方式,包括懒汉式、饿汉式、静态内部类及枚举等方式,并探讨了线程安全性和延迟加载的重要性。

概念:单例模式确保某一个类只有一个实例,并且自行实例化向整个系统提供这个实例。
实现要点

  • 构造器声明为private来隐藏,防止其他类调用
  • private static Singleton实例
  • 获取实例方法声明为public来供系统调用

设计单例类的目标

  • 延迟加载-lazy loading
  • 调用效率
  • 线程安全

懒汉

可以达到lazy-loading,线程不安全,实际不会使用

public class Singleton1 {
    private static Singleton1 instance;
    private Singleton1(){}
    public static Singleton1 getInstance(){
        if(instance == null){
            instance = new Singleton1();
        }
        return instance;
    }
}

懒汉,线程安全

Singleton1的线程安全版本,虽然线程安全但是效率太低,实际中也不会使用,因为对象只有在初始化时需要同步,多数情况下并不需要互斥的获得对象,这种加锁方式会造成巨大无意义的资源消耗,Singleton7的双重校验锁方式对此进行了优化。

public class Singleton2 {
    private static Singleton2 instance;
    private Singleton2(){};
    public static synchronized Singleton2 getInstance(){
        if(instance == null){
            instance = new Singleton2();
        }
        return instance;
    }
}

饿汉

没有做到lazy-loading,实际中这种方式会造成资源浪费,因为系统中很多的类的实例都不会用到,加载类时就实例化太浪费!但是这种方式是线程安全的。

public class Singleton3 {
    private static Singleton3 instance = new Singleton3();
    private Singleton3(){}
    public static Singleton3 getInstance(){
        return instance;
    }
}
//另一种方式
public class Singleton4 {
    private static Singleton4 instance = null;
    static {
        instance = new Singleton4();
    }
    private Singleton4(){}
    public static Singleton4 getInstance(){
        return instance;
    }
}

静态内部类

与上种方式的区别是加了个内部类,这样加载类时并不会实例化instance,只有显式的调用getInstance方法的时候才会实例化,巧妙利用了Java虚拟机的类加载机制,既做到了线程安全,有做到了lazy-loading,实际应用中这种方式是比较推荐的。

public class Singleton5 {
    private static class SingletonHolder{
        private static Singleton5 INSTANCE = new Singleton5();
    }
    private Singleton5(){}
    public static Singleton5 getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

枚举方式

这种方式不仅避免多线程同步问题,还防止反序列化重新创建新的对象

public enum  Singleton6 {
    INSTANCE;
    public void whateverMethod(){}
}

双重校验锁

该方式确保了只有在初始化的时候需要同步,当初始化完成后,再次调用getInstance不会再进入synchronized块。(对Singleton2的改进)但这种方式也被很多人诟病,实际中依然不会采用。
注意这里的instance声明为volatile的必要性
防止指令重排
由于初始化操作 instance=new Singleton()是非原子操作的,主要包含三个过程
1. 给instance分配内存
2. 调用构造函数初始化instance
3. 将instance指向分配的空间(instance指向分配空间后,instance就不为空了)
虽然synchronized块保证了只有一个线程进入同步块,但是在同步块内部JVM出于优化需要可能进行指令重排,例如(1->3->2),instance还没有初始化之前其他线程就会在外部检查到instance不为null,而返回还没有初始化的instance,从而造成逻辑错误。

变量可见性
volatile类型变量可以保证写入对于读取的可见性,JVM不会将volatile变量上的操作与其他内存操作一起重新排序,volatile变量不会被缓存在寄存器,因此保证了检测instance状态时总是检测到instance的最新状态。

public class Singleton7 {
    private volatile static Singleton7 instance;

    private Singleton7() {
    }

    public static Singleton7 getInstance() {
        if (instance == null) {
            synchronized (Singleton7.class) {
                if (instance == null)
                    instance = new Singleton7();
            }
        }
        return instance;
    }
}

以上是实现单例的几种方式汇总,其实综上也能发现在实际中能够付诸使用的方式很少,我们这里更多的是从线程安全和lazy-loading的角度更好的理解和实现单例模式。
在Spring使用ThreadLocal解决线程安全问题。我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,为每个线程提供一个独立的变量副本——”以空间换时间”,这样有状态的Bean就可以在多线程中共享了。 在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简便,且拥有更高的并发性。
参考链接
http://www.blogjava.net/kenzhh/archive/2013/03/15/357824.html
http://blog.youkuaiyun.com/neo_ustc/article/details/7913066
http://blog.youkuaiyun.com/jq_ak47/article/details/54894793

基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)内容概要:本文档围绕基于遗传算法的异构分布式系统任务调度算法展开研究,重点介绍了一种结合遗传算法的新颖优化方法,并通过Matlab代码实现验证其在复杂调度问题中的有效性。文中还涵盖了多种智能优化算法在生产调度、经济调度、车间调度、无人机路径规划、微电网优化等领域的应用案例,展示了从理论建模到仿真实现的完整流程。此外,文档系统梳理了智能优化、机器学习、路径规划、电力系统管理等多个科研方向的技术体系与实际应用场景,强调“借力”工具与创新思维在科研中的重要性。; 适合人群:具备一定Matlab编程基础,从事智能优化、自动化、电力系统、控制工程等相关领域研究的研究生及科研人员,尤其适合正在开展调度优化、路径规划或算法改进类课题的研究者; 使用场景及目标:①学习遗传算法及其他智能优化算法(如粒子群、蜣螂优化、NSGA等)在任务调度中的设计与实现;②掌握Matlab/Simulink在科研仿真中的综合应用;③获取多领域(如微电网、无人机、车间调度)的算法复现与创新思路; 阅读建议:建议按目录顺序系统浏览,重点关注算法原理与代码实现的对应关系,结合提供的网盘资源下载完整代码进行调试与复现,同时注重从已有案例中提炼可迁移的科研方法与创新路径。
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文提出了一种基于非支配排序的蜣螂优化算法(NSDBO),用于求解微电网多目标优化调度问题。该方法结合非支配排序机制,提升了传统蜣螂优化算法在处理多目标问题时的收敛性和分布性,有效解决了微电网调度中经济成本、碳排放、能源利用率等多个相互冲突目标的优化难题。研究构建了包含风、光、储能等多种分布式能源的微电网模型,并通过Matlab代码实现算法仿真,验证了NSDBO在寻找帕累托最优解集方面的优越性能,相较于其他多目标优化算法表现出更强的搜索能力和稳定性。; 适合人群:具备一定电力系统或优化算法基础,从事新能源、微电网、智能优化等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统的多目标优化调度设计;②作为新型智能优化算法的研究与改进基础,用于解决复杂的多目标工程优化问题;③帮助理解非支配排序机制在进化算法中的集成方法及其在实际系统中的仿真实现。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注非支配排序、拥挤度计算和蜣螂行为模拟的结合方式,并可通过替换目标函数或系统参数进行扩展实验,以掌握算法的适应性与调参技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值