资讯专栏INFORMATION COLUMN

设计模式(1)单例模式

zhichangterry / 1021人阅读

摘要:既能保证延迟加载,又能保证线程安全枚举上面的四种方案都有两个弊端需要额外的工作进行序列化,否则每次反序列化的结果都是一个新的实例可通过反射机制强行调用私有构造器实现创建多个对象而这种方案完美的解决了上述两种问题

一.什么是单例模式?

单例是指在程序中某个类只能有一个实例,一些管理器和控制器常被设计成单例模式(如Spring容器的bean实例默认都是单例模式存在的)

二.单例有什么好处?

(1)避免对象的重复创建,减小时间和内存开销
(2)避免由于操作多个对象导致逻辑错误,可以全局统一管理控制



三.怎样创建单例模式?

(1)饿汉模式
public class Singleton1 {
    // 私有化构造函数,保证其它类不能实例化此类
    private Singleton1(){}
    private static Singleton1 instance = new Singleton1();
    //给外界提供一个获取该实例的方法
    public static Singleton1 getInstance() {
        return instance;
    }
}
饿汉模式是实例在类加载的时候创建
好处:避免线程同步问题
缺点:即使这个单例不会被用到也会创建,浪费内存资源

(2)懒汉模式

public class Singleton2 {
    private Singleton2(){}
    private static Singleton2 instance = null;

    public static Singleton2 getInstance() {
        if(instance == null){
            return new Singleton2();
        }
        return instance;
    }
}
懒汉模式是单例在需要的时候才会去创建
好处:按需创建,避免内存资源浪费
坏处:会有线程安全问题产生(需要加锁解决线程同步问题)

(3)双重校验锁

public class Singleton3 {
    private Singleton3(){}
    private static volatile Singleton3 instance = null;

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

上面说到的懒汉模式加同步锁最先想到的可能是在getInstance外直接加synchronized,但仔细想想,每次来拿该对象都需要判断对象锁,这样无疑会降低代码执行效率,所以在同步前先判断对象是否为空,如果不为空直接将对象给它,不需要进行同步操作(这样层序运行过程中最多也只有一次同步锁的判断)你一定还发现对象声明的修饰符多了一个volatile,这就是第二把锁,它能起到禁止指令重排序优化的作用,这样就避免了对象内存地址被赋给instance字段但是构造函数还没调用。(具体原因详见---关于volatile的理解最后一段)

(4)静态内部类

public class Singleton4 {
    private static class Singleton{
        public static Singleton4 instance = new Singleton4();
    }
    private Singleton4(){}
    public static Singleton4 newInstance(){
        return Singleton.instance;
    }
}

与饿汉模式一样同样是利用类加载机制来创建实例,因此不存在多线程并发问题,不同的是它是在内部类里去加载这个实例,所以只要不使用这个内部类,JVM就不会加载这个单例类,也就不会创建对象,实现了懒汉式的延迟加载。既能保证延迟加载,又能保证线程安全

(5)枚举

public enum Singleton5 {
    instance;
    public void whateverMethod(){}
}

上面的四种方案都有两个弊端:

1)需要额外的工作进行序列化,否则每次反序列化的结果都是一个新的实例
2)可通过反射机制强行调用私有构造器实现创建多个对象

而这种方案完美的解决了上述两种问题

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69082.html

相关文章

  • Java 设计模式单例模式

    摘要:在设计模式一书中,将单例模式称作单件模式。通过关键字,来保证不会同时有两个线程进入该方法的实例对象改善多线程问题为了符合大多数程序,很明显地,我们需要确保单例模式能在多线程的情况下正常工作。 在《Head First 设计模式》一书中,将单例模式称作单件模式。这里为了适应大环境,把它称之为大家更熟悉的单例模式。 一、了解单例模式 1.1 什么是单例模式 单例模式确保一个类只有一个实例,...

    everfight 评论0 收藏0
  • JavaScript设计模式----单例模式

    摘要:不符合设计模式中的单一职责的概念。引入代理实现单例模式引入代理实现单例模式的特点我们负责管理单例的逻辑移到了代理类中。的单例模式对比在以上的代码中实现的单例模式都混入了传统面向对象语言的特点。 声明:这个系列为阅读《JavaScript设计模式与开发实践》 ----曾探@著一书的读书笔记 1.单例模式的特点和定义 保证一个类仅有一个实例,并且提供一个访问它的全局访问点。 2.传统面向对...

    selfimpr 评论0 收藏0
  • 面试官所认为的单例模式

    摘要:防止指令重排序防止时指令重排序导致其他线程获取到未初始化完的对象。枚举类默认枚举实例的创建是线程安全的,所以不需要担心线程安全的问题。 单例模式是23种GOF模式中最简单,也是最经常出现的一种设计模式,也是面试官最常爱考的一种模式,为什么呢?因为单例模式足够简单,编写一个单例模式代码几分钟就能搞定,所以设计模式中面试官通常会选取单例模式作为出题。下面把单例模式分几个点,分别说说哪些地方...

    codeKK 评论0 收藏0
  • 【JavaScript设计模式单例模式

    摘要:此时我们创建的对象内保存静态变量通过取值器访问,最后将这个对象作为一个单例放在全局空间里面作为静态变量单例对象供他人使用。 单例模式 又被称为单体模式,是只允许实例化一次的对象类。有时我们也用一个对象来规划一个命名空间,井井有条的管理对象上面的属性和方法。 传统的面向对象语言中单例模式的实现,均是单例对象从类中创建而来,在以类为中心的语言中,这是很常见的做法。如果需要某个对象,就必须先...

    zhaot 评论0 收藏0
  • JavaScript设计模式-第一部分:单例模式、组合模式和外观模式

    摘要:但是,这并不是采用单例的唯一原因。使用命名空间单例模式也被称为模块设计模式。函数内部声明了一些局部函数和或变量。紧随函数声明放置即可立即执行外部函数,并将所得的对象文字费赔给变量。 JavaScript设计模式-第一部分:单例模式、组合模式和外观模式 设计模式是一些可靠的编程方式,有助于保证代码更加易于维护、扩展及分离,所有设计模式在创建大型JavaScript应用程序时均不可或缺 单...

    betacat 评论0 收藏0
  • Java设计模式优化-单例模式

    摘要:单例模式概述单例模式是一种对象创建模式,用于产生一个类的具体事例。所以解决了线程安全问题参考失效原因和解决方案中单例模式的缺陷及单例的正确写法懒汉式静态内部类私有构造器获取单例的方法静态内部类持有单例作为静态属性。 单例模式概述 单例模式是一种对象创建模式,用于产生一个类的具体事例。使用单例模式可以确保整个系统中单例类只产生一个实例。有下面两大好处: 对于频繁创建的对象,节省初第一...

    eccozhou 评论0 收藏0

发表评论

0条评论

zhichangterry

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<