美文网首页
单例模式的作用及创建方法

单例模式的作用及创建方法

作者: ZMRWEGo | 来源:发表于2018-10-17 17:05 被阅读5次

单例模式作为常见的设计模式之一,在java的项目开发中会时常的用到。Java Singleton模式即保证在JVM运行时,一个类Class只有一个实例存在。


一、单例模式的作用

单例模式有什么好处呢?
最简单的一个例子就是网站计数器的设计了。当我们想要统计当前网站的在线人数时,一个显而易见的问题就是并发所带来的线程安全问题,当我们对这个计数器(网站人数)在同一时刻进行操作,再保存计数时就会造成数据的混乱,后者覆盖前者的结果。一种解决方案就是把这个计数器设置为唯一对象,所有人都必须共用同一份数据。
实现唯一对象最好的解决办法就是让类自己负责保存它的唯一实例,并且让这个类保证不会产生第二个实例,同时提供一个让外部对象访问该实例的方法。自己的事情自己办,而不是由别人代办,这非常符合面向对象的封装原则。

二、单例模式的创建

单例模式的三个特点:

  • 单例类确保自己只有一个实例
  • 单例类必须自己创建自己的实例
  • 单例类必须为其他对象提供唯一的实例
    单例模式的实现方法有许多种,下面介绍几种常用的实现方法

1. 懒汉式

只有在自身需要的时候才会行动,从来不知道及早做好准备。它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回。

/**
 * @author zmrwego
 * @descreption
 *
 * 懒汉式,线程不安全的
 *
 * @create 2018-10-17
 **/

public class Singleton1 {
    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
    private static Singleton1 instance = null;
    //私有构造器,只允许自己实例化自己
    private Singleton1(){}
    //懒汉式 静态方法,创建实例
    public static Singleton1 getInstance(){
        if(instance == null){
            instance = new Singleton1();
        }
        return instance;
    }

}

该方法在多线程情况下有可能重复创建实例,以下是线程安全的懒汉模式


/**
 * @author zmrwego
 * @descreption 懒汉式变种,加同步锁
 * @create 2018-10-17
 **/

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

这种模式的缺点是加锁造成了效率下降,并且在绝大部分情况下是不需要同步的。使用双重检验锁(DCL),只在第一次初始化的时候进行同步加锁

/**
 * @author zmrwego
 * @descreption、
 *
 *懒汉模式下的双重检验锁,使用volatile关键字
 *防止jvm指令重排序的优化导致的
 *
 * @create 2018-10-17
 **/

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

2. 饿汉式

该方式在类加载的时候就被实例化了。


public class Singleton {
    //声明为静态对象,在类加载时即创建好了实例
    private static Singleton instance = new Singleton();
    private Singleton(){}
    //
    private static Singleton getInstance(){
        return instance;
    }
}

3. 静态内部类

这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟饿汉不同的是(很细微的差别):饿汉方式是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显式通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。

public class Singleton {
    //    静态内部类
    private static class SingletonHoder {
        private static Singleton instance = new Singleton();
    }

    private Singleton() {=o}

    public static Singleton getInstance() {
        return SingletonHoder.instance;
    }
}

想象一下,如果实例化instance很消耗资源,我想让它延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式就显得很合理。


关于类加载情况下单例模式,如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些servlet容器对每个servlet使用完全不同的类 装载器,这样的话如果有两个servlet访问一个单例类,它们就都会有各自的实例。修复的办法是

相关文章

  • 单例模式的作用及创建方法

    单例模式作为常见的设计模式之一,在java的项目开发中会时常的用到。Java Singleton模式即保证在JVM...

  • 创建型模式——单例模式

    单例模式简介 单例模式是java创建型模式之一,主要作用是创建唯一对象。 单例模式特点:1.单例类只有一个实例。2...

  • OC - 单例模式

    导读: 一、什么是单例模式 二、单例的作用 三、常见的单例类 四、自定义单例类的方法 一、什么是单例模式 单例模式...

  • Java设计模式

    1、单例模式:某个类只能有一个实例,这个实例必须自行创建,必须提供对外提供唯一调用它的方法 单例模式的作用...

  • python面试题-2018.1.30

    问题:如何实现单例模式? 通过new方法来实现单例模式。 变体: 通过装饰器来实现单例模式 通过元类来创建单例模式...

  • 单例模式、异常、模块

    单例模式 创建单例-保证只有1个对象 创建单例时,只执行1次init方法 目的 —— 让 类 创建的对象,在系统中...

  • 设计模式之单例模式

    1 什么是单例模式 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个...

  • 逸笔记-设计模式-单例模式

    1.什么是单例模式 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个...

  • 单例模式

    1. 什么是单例模式? 创建单例类的方法叫单例模式. 单例类, 就是只能产生一个对象的类. 2. 为什么使用单例模...

  • PHP设计模式—创建型设计模式

    ** 创建型设计模式 **: 单例模式(Singleton Pattern) 工厂方法模式(Factor Patt...

网友评论

      本文标题:单例模式的作用及创建方法

      本文链接:https://www.haomeiwen.com/subject/hhlrzftx.html