【设计模式系列】单例模式的7种写法

前言

单例模式是一种常用的软件设计模式,在他的核心结构中只包含一个被称为 单例的特殊类。通过单例模式可以保证系统只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

Singletom类,定义一个GetInstance操作,允许客户访问他的唯一实例,GetInstance是一个静态方法,主要负责创建自己的唯一实例。

一、实现

1、饿汉式

public class Singleton {
        private static Singleton singleton = new Singleton();
        private Singleton(){}
        public static Singleton getInstance(){             return singleton;         } }

优点:在类加载时就完成了对象的初始化,所以类加载比较慢,但是获取对象的速度比较快。

缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

2、懒汉式(线程不安全)

public class Singleton {
        private static Singleton singleton ;
        private Singleton() {}
         public static Singleton getInstance(){                 if(singleton == null){          singleton = new Singleton();          }     return singleton;    } }  

优点:这种写法起到了延迟加载的效果,但是只能在单线程下使用。

缺点:如果在多线程下,一个线程进入了if(singleton == null )判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可以使用这种方式。

3、懒汉式(线程安全)

public class Singleton {
        private static Singleton singleton ;
        public static Singleton getInstance(){
            synchronized (Singleton.class) {
            if(singleton == null){
                    singleton = new Singleton();
                }
            }
            return singleton;
        }
}  

或者

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

优点:解决了上面线程不安全的问题

缺点:效率太低,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步,而其实这个方法只执行一次实例化代码六够了,后面的想获得该实例,直接return就就好了。方法进行同步效率太低。

4、双重检查式(DCL:Double-checked locking)

public class Singleton {
    private static Singleton singleton;
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}  

优点:线程安全、延迟加载、效率较高。

这种写法在getInstance()方法中进行了两次空判断,第一次是为了避免不必要的同步,第二次是在singleton为空的情况下才创建实例。DCL虽然在一定程度上解决了资源的消耗和多余的同步,线程安全等问题,但是在某些情况下会出现DCL失效。有些书中建议使用静态内部类单例模式来代理DCL。

5、静态内部类单例模式

public class Singleton {
    public static Singleton getInstance() {
        return SingletonHolder.singleton;
    }
    private static class SingletonHolder {
        private static final Singleton singleton = new Singleton();
    }
}  

加载一个类时,其内部的类不会同时被加载,当且仅当某个静态成员(静态成员变量、构造方法、静态方法)被调用时才去加载。第一次加载Singleton时并不会初始化Singleton,只有第一次调用getInstance()方法时才会加载SingletonHolder,并且初始化Singleton,这样不仅能够保证线程的安全性也能保证Singleton类的唯一性。推荐使用中这种方式。

6、枚举单例

public enum Singleton{
        INSTANCE;
        public void doSomething(){

        }
}  

优点:通过Singleton.INSTANCE来访问,比较方便,线程安全,防止反序列化创建新的对象,

缺点:失去了一些类的特性,没有延迟加载,可读性差

7、容器式

public class SingletonManager {
        public static Map<String, Object> objMap = new HashMap<String, Object>();
        public static void registerService(String key,Object instance){
            if(!objMap.containsKey(key)){
                objMap.put(key, instance);
            }
        }
        public static Object getService(String key){
            return objMap.get(key);
        }
}  

 用SingletonManager将多个单例统一进行管理,使用时根据key获取对应的实例,这种方式可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,屏蔽了内部实现细节,降低了耦合度。 

原文地址:https://www.cnblogs.com/dream-to-pku/p/9176072.html

时间: 2024-10-18 11:34:34

【设计模式系列】单例模式的7种写法的相关文章

Java设计模式之单例模式(七种写法)

Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleton instance; private Singleton (){}//私有化构造方法,防止类被实例化 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } retu

Android设计模式之单例模式的七种写法

一 单例模式介绍及它的使用场景 单例模式是应用最广的模式,也是我最先知道的一种设计模式.在深入了解单例模式之前.每当遇到如:getInstance()这样的创建实例的代码时,我都会把它当做一种单例模式的实现. 事实上常常使用的图片载入框架ImageLoader的实例创建就是使用了单例模式.由于这个ImageLoader中含有线程池.缓存系统.网络请求,非常消耗资源,不应该创建多个对象,这时候就须要用到单例模式. ImageLoader的创建代码例如以下: ImageLoader.getInsta

设计模式之单例模式的几种写法——java

对于设计模式的使用场景和好处,之前有介绍一篇,今天主要是单例模式的编写方式,直接看代码吧 单例模式之饿汉模式,不会懒加载.线程安全 /** * @Author wangtao * @Description 单例模式之饿汉模式,不会懒加载.线程安全 * @Date 2019-5-22 12:32 * @优点 线程安全,简单易实现 * @缺点 在进行类加载的时候就创建好实例,会占用内存 **/ class SingletonHungry{ //私有构造函数 private SingletonHung

单例模式的几种写法的差异

设计模式:单例模式的几种写法的差异 1.单例模式的概念 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象. 注意: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 2.单例模式

单例模式的八种写法比较

单例模式是最常用到的设计模式之一,熟悉设计模式的朋友对单例模式都不会陌生.一般介绍单例模式的书籍都会提到 饿汉式 和 懒汉式 这两种实现方式.但是除了这两种方式,本文还会介绍其他几种实现单例的方式,让我们来一起看看吧. 简介 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在. 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象

单例模式的 几种写法

1 首先要知道,什么叫做单例模式. 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例 2 单例模式简介 单例模式是设计模式中最简单的形式之一.这一模式的目的是使得类的一个对象成为系统中的唯一实例.要实现这一点,可以从客户端对其进行实例化开始.因此需要用一种只允许生成对象类的唯一实例的机制,"阻止"所有想要生成对象的访问.使用工厂方法来限制实例化过程.这个方法应该是静态方法(类方法),因

面试中单例模式有几种写法?

"你知道茴香豆的'茴'字有几种写法吗?" 纠结单例模式有几种写法有用吗?有点用,面试中经常选择其中一种或几种写法作为话头,考查设计模式和coding style的同时,还很容易扩展到其他问题.这里讲解几种猴子常用的写法,但切忌生搬硬套,去记"茴香豆的写法".编程最大的乐趣在于"know everything, control everything".猴子 JDK版本:oracle java 1.8.0_102 大体可分为4类,下面分别介绍他们的基

C# 单例模式的五种写法

C# 单例模式的五种写法及优劣分析,见下文: [单例模式及常见写法](http://blog.csdn.net/jiankunking/article/details/50867050)

单例模式的五种写法

首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了,比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,即在整个的打印过程中我只有一个打印程序的实例. 简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中, 任何一个时刻,单例类的实例都只存在一个(当然也可以不存在). package singleton; /** * @author lei * 单例模式的五种写法: *

【JAVA学习】单例模式的七种写法

尊重版权:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): Java代码   public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } retur