美文网首页java
设计模式--单例模式

设计模式--单例模式

作者: 是哪的鸭 | 来源:发表于2020-02-19 19:11 被阅读0次

单例模式

一个类只能有一个对象。该类自己负责创建对象,同时确保只有一个对象被创建。

  1. 单例类只能有一个实例
  2. 单例类必须自己创建自己的唯一实例
  3. 单例类必须给其他所有类提供这一实例

使用场景:

  • 要求产生唯一的序列号
  • WEB中的技术去,不用每次刷新都在书库里加一次。用单例先缓起来
  • 创建的一个对象需要消耗的资源过多,比如I/O与数据库的连接等。

实现方法

1.懒汉式

Lazy初始化:
线程安全:
描述: 最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

具体实现

//懒汉式线程安全做法为加锁,在getInstance方法上加sychronized锁。但是这样会影响效率
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
     //doSomething() 该实例支持的行为
}

2.饿汉式

Lazy初始化:
线程安全:
描述: 常用方法,但是容易产生垃圾对象。基于classloader机制避免了多线程的同步问题。在类加载时就实例化对象,没达到lazy loading效果

  • 优点:没有加锁,效率高
  • 缺点:类加载时就初始化,可能会产生垃圾

具体实现

public class Singleton{
    private static Singleton instance=new Singleton();
    private Singleton(){};
    public static Singleton getInstance(){
        return instance;
    }
     //doSomething() 该实例支持的行为
}

3.双检锁/双重校验锁(DCL)

JDK版本: 1.5起
Lazy初始化:
多线程安全:
描述: 采用双锁机制,安全且在多线程情况下能保持高性能。getInstance()的性能对程序很关键。

具体实现

public class Singleton{
    //当singleton不为null时通知想要实例化的其他线程  
    private volatile static Singleton singleton;
    private Singleton(){};
    public Singleton getInstance(){
        //判断是否为空,为空则获得sychronized锁
        if(instance==null){
            sychronized(Singleton.class);
            //获得sychronized锁后再次判断,防止获得锁时,已经被实例化。
            if(singleton==null){
                singleton=new Singleton();
            }
        }
        return singleton;
    }
    
     //doSomething() 该实例支持的行为
}

登记式/静态内部类

Lazy初始化:
线程安全:
描述: 能达到双检锁一样的功效。但是实现更简单。本方法采用classloader机制来确保初始化时只有一个线程。同饿汉式不同,饿汉式只要类被加载了,instance一定被实例化。本方法只有通过主动调用getInstance()来显示装在SingletonHolder,从而实例化instance

具体实现

    public class Singleton{
        private static class SingletonHolder{
            private static final Singleton INSTANCE =new Singleton();
        }
        private Singleton(){};
        public static final Singleton getInstance(){
            return SingletonHolder.INSTANCE;
        }
        
         //doSomething() 该实例支持的行为
    }

6.枚举

JDK版本: 1.5起
是否Lazy初始化:
多线程安全:
描述: 实现单例模式的最佳方法。简洁,而且支持序列化机制,绝对防止多次被实例化。代码可读性差

具体实现

    public enum Singleton{
        INSTANCE
        
        //doSomething() 该实例支持的行为
        
        //可以省略此方法,通过Single.INSTANCE进行操作
        public static Singleton getInstance(){
            return Singleton.INSTANCE
        }
        
    }

总结

枚举式不常用,可读性差。
既要求线程安全,又要求Lazy加载使用双检锁式。
要求线程安全,不要求Lazy加载使用饿汉式。

注意: 前五种方法可能会多次实例化,当实例被写入到文件到反序列化成实例时,会重复实例化。为了避免这种情况。如果涉及到序列化、反序列化时,我们需要重写readResolve方法,以让实例唯一。

private Object readResolve() throws ObjectStreamException{
    return singleton;
}

相关文章

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 基础设计模式:单例模式+工厂模式+注册树模式

    基础设计模式:单例模式+工厂模式+注册树模式 单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象...

  • 单例模式

    JAVA设计模式之单例模式 十种常用的设计模式 概念: java中单例模式是一种常见的设计模式,单例模式的写法...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

网友评论

    本文标题:设计模式--单例模式

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