设计模式~单列模式-01

简介: 单列模式1、饿汉式2、懒汉式(lazy loading)3、双重检测4、静态内部类

单列模式

1、饿汉式

2、懒汉式(lazy loading)

3、双重检测

4、静态内部类(完美)

5、枚举单列(最完美)


       单例模式就是为了确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。单例模式控制控制对象不要反复创建,提高我们工作的效率。减少资源的占用。

       【解释:我有 6 个漂亮的老婆,她们的老公都是我,我就是我们家里的老公 Sigleton,她们只要说道「老公」,都是指的同一个人,那就是我 。】

(1)单例模式下类的组成部分:

       1.私有的构造方法。

       2.私有的当前类对象作为静态属性。

       3.公有的向外界提供当前类对象的静态方法。

主要的两种实现方式:

       饿汉式:线程安全,调用效率高,不能延时加载。

       懒汉式:线程安全,调用效率不高,可以延时加载。

其他方式:

       双重检测锁式:极端情况下偶尔会出现问题,不建议使用。

       静态内部类式:线程安全,调用效率高,可以延时加载。

       枚举式:线程安全,调用效率高,不能延时加载。

2懒汉式饿汉式的区别

       “懒汉式”是在你真正用到的时候才去建这个单例对象“饿汉式”是在不管用不用得上,一开始就建立这个单例对象

       从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题,写法简单明了,能用则用。但是它是加载类时创建实例。

       饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的。

       只是一个语法的标识,就好比文档中的句号和逗号差不多,代表当前是一个完整的语句,和下一个语法分开,如果仅仅只有一句,加不加无所谓,但是多个语句时,要区分,否则编译器不知道你的语法。

1、饿汉式

       类加载到内存后,就实例化一个单例,JVM保证线程安全。

       简单实用,推荐使用!

       唯一缺点:不管用到与否,类装载时就完成实例化。

public class Singleton01 {
    //持有私有静态实例,防止被引用
private static final Singleton01 INSTANCE = new Singleton01();
//    private static final Singleton01 INSTANCE;
//    static {
//        INSTANCE = new Singleton01();
//    }
//私有构造方法,防止被实例化
//只有本类能调用,只能Singleton01 Singleton = Singleton01.getInstance();调用
private Singleton01() {};//分号:增加语法的可读性
/*只是一个语法的标识,就好比文档中的句号和逗号差不多,代表当前是一个完整的语句,和下一个语法分开,如果仅仅只有一句,加不加无所谓,但是多个语句时,要区分,否则编译器不知道你的语法。*/
//懒汉式,静态工程方法,创建实例
    public static Singleton01 getInstance() {
        return INSTANCE;
}
//可有可无
    public void m() {
        System.out.println("m");
    }
    public static void main(String[] args) {
        Singleton01 m1 = Singleton01.getInstance();
        Singleton01 m2 = Singleton01.getInstance();
        System.out.println(m1 == m2);
    }
}

2、懒汉式lazy loading

       虽然达到了按需初始化的目的,但却带来线程不安全的问题。

       可以通过synchronized解决,但也带来效率下降。延迟加载,也叫作懒加载,等到真正用的时候才加载。

public class Singleton02 {
//持有私有静态实例,防止被引用
    private static Singleton04 INSTANCE;
    //私有构造方法,防止被实例化
    private Singleton02() {
    }
    //懒汉式,静态工程方法,创建实例
    //加锁(synchronized)效率下降
    public static /*synchronized*/ Singleton02 getInstance() {
        if (INSTANCE == null) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //妄图通过减小同步代码块的方式提高效率,然后不可行
//            synchronized (Singleton02.class) {
//                try {
//                    Thread.sleep(1);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            INSTANCE = new Singleton02();
        }
        return INSTANCE;
    }
    public void m() {
        System.out.println("m");
    }
    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Singleton02.getInstance().hashCode());
            }).start();
        }
    }
}

3、双重检测

       保证线程安全;以前认为是最完美的方式。

public class Singleton03 {
    //volatile:不写,会出现。volatile 防止指令重排和可见性
    private static volatile Singleton03 INSTANCE; //JIT
    private Singleton03() {
    }
public static Singleton03 getInstance() {
//判断对象是否已经实例化,只有非实例化的情况下才能进入if块进行加锁。
        if (INSTANCE == null) {
            //双重检查:保证线程安全;以前认为是最完美的方式
            synchronized (Singleton03.class) {
//避免 SingletonTon== null时,第一个线程实例化后,进入阻塞状态的线程被唤醒后仍会进行实例化。
                if(INSTANCE == null) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Singleton03();
                }
            }
        }
        return INSTANCE;
    }
    public void m() {
        System.out.println("m");
    }
    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Singleton03.getInstance().hashCode());
            }).start();
        }
    }
}

4、静态内部类(完美)

       静态内部类方式,完美。JVM保证单例线程安全,加载外部类时不会加载内部类,这样可以实现懒加载。

public class Singleton04 {//JVM只加载一次
//私有构造方法
    private Singleton04() {
    }
    //静态内部类,初始化04
private static class Singleton07Holder {
//组合外部类对象作为属性
        private final static Singleton04 INSTANCE = new Singleton04();//出现延迟加载
    }
    public static Singleton04 getInstance() {
        return Singleton04Holder.INSTANCE;
    }
    public void m() {
        System.out.println("m");
    }
    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Singleton04.getInstance().hashCode());
            }).start();
        }
    }
}

5、枚举单列最完美

       不仅可以解决线程同步,还可以防止反序列化。由JVM从根本上提供保障!避免通过反射和反序列化的漏洞!

public enum Singletontonton05 {
    INSTANCE;
    public void m() {}
    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
                System.out.println(Singletonton05.INSTANCE.hashCode());
            }).start();
        }
    }
}


目录
相关文章
|
设计模式 算法 关系型数据库
23种设计模式总结
23种设计模式总结
117 0
|
存储 算法 前端开发
设计模式大全
转自:http://blog.csdn.net/longronglin/article/details/1454315 Longronglin之设计模式: Christopher Alexander 说过:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。 模式描述为:在一定环境中解决某一问
2416 0
|
设计模式
我所认识的设计模式
我所认识的设计模式
75 0
|
设计模式 存储 监控
设计模式(C++版)
看懂UML类图和时序图30分钟学会UML类图设计原则单一职责原则定义:单一职责原则,所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。bad case:IPhone类承担了协议管理(Dial、HangUp)、数据传送(Chat)。good case:里式替换原则定义:里氏代换原则(Liskov 
36114 17
设计模式(C++版)
|
设计模式 消息中间件 Java
一起来学设计模式之认识设计模式
前言 目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本节给大家讲一下设计模式基本概念,它的基本原则以及有哪些设计模式~ 本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~ 设计模式初识 设计模式是一种经过验证的、被广泛应用的解决特定问题的软件设计方案,它提供了一种在软件设计中反复使用的解决方案。设计模式通常描述了一个问题的情境、解决方案和解决方案的优点和缺点。设计模式不是一种具体的编程语言特性或库,而是一种通用的设计思想和方法。
|
算法 容器 设计模式
24种设计模式
Factory Pattern(工厂模式):1. 创建对象的接口,封装对象的创建;2. 使具体化类的工作延迟到子类中。(维护一类对象) AbstractFactory Pattern(抽象工厂 模型):该模式将一组对象的创建封装到一个用于创建对象的类中。
892 0
|
设计模式
|
设计模式 存储 缓存

热门文章

最新文章