美文网首页
2_单例模式

2_单例模式

作者: 真是个点子王 | 来源:发表于2020-12-23 11:34 被阅读0次
  • 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式;
  • 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代码模式;
  • 行为型模式:模板方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式

单例模式

  • 单例模式就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得对象实例的方法。
  • Java写法分类
    • 饿汉式(静态常量)
    • 饿汉式(静态代码块)
    • 懒汉式(线程不安全)
    • 懒汉式(线程安全)
    • Double Check
    • 静态内部类
    • 枚举

一、饿汉式(静态常量)

  • 步骤如下:
    • 1、构造器私有化;
    • 2、类的内部创建对象;
    • 3、向外暴露一个静态的方法;
    • 4、代码实现
public class SingletonTest01 {
    public static void main(String[] args) {
        PersonManager manager = PersonManager.getInstance();
        PersonManager manager1 = PersonManager.getInstance();
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
    }
}

class PersonManager{
    // 2. 创建静态成员变量
    private static final PersonManager INSTANCE = new PersonManager();
    // 1. 将构造器私有化
    private PersonManager(){
    }
    // 3.提供一个静态方法,返回实例对象
    public static PersonManager getInstance() {
        return INSTANCE;
    }
}

优缺点:

  • 1、优点:写法简单,就是在类加载的时候就完成实例化。避免了线程同步问题;
  • 2、缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终未使用过这个实例,则会造成内存的浪费。
    • 关于类加载的机制,这一块还没有学习。需要留个坑,以及为何会存在线程同步问题,也不能够理解。

二、饿汉式(静态代码块)

  • 这种方式原理和方式一中相同,只不过是将静态变量的初始化操作放在了静态代码块中。
public class SingletonTest02 {
    public static void main(String[] args) {
        PersonManager02 manager = PersonManager02.getInstance();
        PersonManager02 manager1 = PersonManager02.getInstance();
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
    }
}

class PersonManager02{

    private static final PersonManager02 INSTANCE;

    static {
        INSTANCE = new PersonManager02();
    }
    private PersonManager02(){

    }

    public static PersonManager02 getInstance(){
        return INSTANCE;
    }

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

  • 在真正需要使用到类的对象的时候才去创建它。
public class Singleton03 {
    public static void main(String[] args) {
        PersonManager03 manager = PersonManager03.getInstance();
        PersonManager03 manager1 = PersonManager03.getInstance();
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
    }

}

class PersonManager03{
    private static PersonManager03 instance;
    private PersonManager03(){
    }
    public static PersonManager03 getInstance(){
        if(instance == null){
            instance = new PersonManager03();
        }
        return instance;
    }
}
  • 可以起到懒加载的效果,但是只能在单线程下使用;
  • 如果在多线程下,一个程序如果进入了if(instance == null)语句块,但是在还没有创建对象时,另外一个线程也进入了该块,会产生线程安全问题。

四、懒汉式(线程安全)

  • getInstance()方法加上synchronized可以解决线程安全问题
public class Singleton04 {
    public static void main(String[] args) {
        PersonManager04 manager = PersonManager04.getInstance();
        PersonManager04 manager1 = PersonManager04.getInstance();
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
    }
}

class PersonManager04{
    private static PersonManager04 instance;
    private PersonManager04(){
    }
    public static synchronized PersonManager04 getInstance(){
        if(instance == null){
            instance = new PersonManager04();
        }
        return instance;
    }
}
  • 虽然解决了线程安全问题,但是效率太低。例如,后续操作可能只是单独的想获得该类的实例对象,但是每一次都需要进入到同步代码块中,太低效。

五、Double Check

public class Singleton05 {
    public static void main(String[] args) {
        PersonManager05 manager = PersonManager05.getInstance();
        PersonManager05 manager1 = PersonManager05.getInstance();
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
    }

}

class PersonManager05{

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

        }
        return instance;
    }
}

六、静态内部类

  • 静态内部类在其所属的类加载时, 内部类本身不发生加载;
  • 当真正用到它时,才会加载(实现了延迟加载);
  • 在类加载时初始化,线程安全。
  • 步骤:
public class SingletonTest06 {
    public static void main(String[] args) {
        PersonManager05 manager = PersonManager05.getInstance();
        PersonManager05 manager1 = PersonManager05.getInstance();
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
    }
}

class PersonManager06 {
 
    // 1、私有化构造器
    private PersonManager06(){
    }

    // 2、写一个静态内部类,该类中有一个静态属性Person
    private static class PersonInstance{
        private static final PersonManager06 INSTANCE = new PersonManager06();
    }

    // 3、提供一个静态的公有方法,直接返回Person.INSTANCE
    public static PersonManager06 getInstance(){
        return PersonInstance.INSTANCE;
    }
}

七、枚举

public class SingletonTest07 {
    public static void main(String[] args) {
        PersonManager07 manager = PersonManager07.INSTANCE;
        PersonManager07 manager1 = PersonManager07.INSTANCE;
        System.out.println(manager == manager1);
        System.out.println(manager.hashCode());
        System.out.println(manager1.hashCode());
        manager.sayOK();
    }
}

enum PersonManager07{
    INSTANCE;
    public void sayOK(){
        System.out.println("ok");
    }
}

实例

相关文章

  • 2_单例模式

    创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式; 结构型模式:适配器模式、桥接模式、装饰模式、...

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

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

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

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

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

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

网友评论

      本文标题:2_单例模式

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