java设计模式之单例模式

设计模式之单例模式

单例模式(Singleton)是设计模式一种,属于建造型的模式。
单例模式,顾名思义就是只有一个实例,该类确保单个对象被创建,可以直接访问,不需要实例化该类的对象,以下是几种创建单例模式的方式

饿汉式

特点

  1. 私有化构造方法
  2. 类加载到内存的时候初始化(类只会加载一次(双亲委派机制),保证实例唯一)
  3. 提供对外获取实例的静态方法
  4. JVM保证线程安全
  5. 比较常用,但容易产生垃圾,因为一开始就初始化
第1种写法
  • 静态对象,类加载时候初始化
public class Singleton1 {
    private static final Singleton1 INSTANCE= new Singleton1();
    
    public static Singleton1 getInstance() {
        return INSTANCE;
    }
    
    private Singleton1() {
    }
}
第2种写法
  • 静态块初始化对象,和第1种一个意思
public class Singleton2 {
    private static final Singleton2 INSTANCE;
    static {
        INSTANCE= new Singleton2();
    }
    
    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        return INSTANCE;
    }
}

懒汉式

特点

  1. 私有化构造方法
  2. 使用的时候才会初始化
  3. 提供对外获取实例的静态方法
第1种写法
  • 使用静态内部类的方式,JVM保证单例,加载外部类时不会加载内部类,这样可以实现懒加载,线程安全
public class Singleton1 {
    private static class Singleton1Holder {
        private static final Singleton1 INSTANCE= new Singleton1();
    }
    
    public static Singleton1 getInstance() {
        return Singleton1Holder.INSTANCE;
    }
    
    private Singleton1() {
    }
}
第2种写法
  • 虽然达到了按需加载的方式,但是线程不安全
public class Singleton2 {
    private static Singleton2 INSTANCE;

    private Singleton2 () {
    }

    public static Singleton2 getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton2 ();
        }
        return INSTANCE;
    }
}
第3种写法
  • 使用synchronized关键字,可以保证线程安全性,但是上来就加锁,锁粒度高,效率低
public class Singleton3 {
    private static Singleton3 INSTANCE;

    private Singleton3() {
    }

    public static synchronized Singleton3 getInstance() {
        if (INSTANCE == null) {
            return new Singleton3();
        }
        return INSTANCE;
    }
}
第4种写法
  • 同样使用synchronized关键字,但做了双重检查(DCL),线程安全,实现延迟初始化,多线程情况下能保持高性能
public class Singleton4 {
    private static volatile Singleton4 INSTANCE; 
    private Mgr06() {
    }

    public static Singleton4 getInstance() {
        if (INSTANCE == null) {
            //双重检查
            synchronized (Singleton4.class) {
                if(INSTANCE == null) {
                    INSTANCE = new Singleton4();
                }
            }
        }
        return INSTANCE;
    }
}
  • 第一次判断INSTANCE == null,为了不必要的加锁,提高性能,如果有一个线程已经创建了,就直接返回该对象
  • 第二次判断INSTANCE == null,为了进行同步,避免多线程问题
  • INSTANCE = new Singleton4()对象的创建在JVM中可能会进行重排序,多线程情况下,创建的对象可能是半初始化状态,使用volatile关键字可以禁止指令重排,解决该问题

枚举模式

特点

  1. 枚举类隐藏了私有的构造器。
  2. 枚举类的域 是相应类型的一个实例对象
  3. 防止反序列化
  4. 线程安全
  5. 《Effective Java》书中推荐的单例模式,日常开发中很少用
写法
public enum Singleton1{
    INSTANCE;
}
  • Disruptor单机最快MQ,使用枚举单例来创建守护线程
package com.lmax.disruptor.util;

import java.util.concurrent.ThreadFactory;

/**
 * Access to a ThreadFactory instance. All threads are created with setDaemon(true).
 */
public enum DaemonThreadFactory implements ThreadFactory
{
    INSTANCE;

    @Override
    public Thread newThread(final Runnable r)
    {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
}

总结

  • 日常开发中 一般采用饿汉式,若对资源十分在意可以采用静态内部类(既保证懒加载又保证安全性),不建议采用懒汉式及双重检测
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。 2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等 3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧 课程内容和目标 本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式 1) 内容包括: 设计模式七大原则(一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页