我是靠谱客的博主 淡然溪流,最近开发中收集的这篇文章主要介绍设计模式-创建型模式-单例模式-1创建型模式-1,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

创建型模式-1

1.单例模式

1.1 介绍

单例模式 singleton pattern :用来保证一个对象只会创建一个实例是最常用的设计模式,它具有易于理解,使用简便.但有时候在过度的使用会有适得其反的效果; 就比如单例懒加载一个大对象,在使用的时候在加载就会有明显的延迟;

1.2 单例模式V1

下面是最简单的单例模式

public class SingletonV1 {

    public static SingletonV1 singleton;

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

这样的单例模式在单线程的环境下面是没有问题的,当运行在多线的环境下面就是两个线程会同事的调用getInstance() 方法的时候,第一个线程正在实例化对象还没有完全的创建成功,又有一个线程在执行有去实例化一次

1.3 单例模式V2

class SingletonV2 {
    public static SingletonV2 singleton;

    private SingletonV2(){}

    public static synchronized SingletonV2 getInstance(){
        if(singleton ==null){
            singleton = new SingletonV2();
        }
        return singleton;
    }
}

1.4 单例模式V3

class SingletonV3 {
    public static SingletonV3 singleton;

    private SingletonV3(){}

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

上面两个版本是一样的都使用了synchronized 的关键字来是的方法同步,只有一个线程可以访问,这样基于导致了效率下降

1.5 双重校验机制的同步锁单例模式V4

class SingletonV4 {
    public static SingletonV4 singleton;

    private SingletonV4() {
    }

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

1.6 voletile 单例模式V5

class SingletonV4 {
    public static volatile SingletonV4 singleton;

    private SingletonV4() {
    }

    public static SingletonV4 getInstance() {
        if (singleton == null) {
            synchronized (SingletonV4.class) {
                if (singleton == null) {
                    singleton = new SingletonV4();//这一步
                }
            }
        }
        return singleton;
    }
}

修复V4 版本可能出现的指令排序 因为在上面的哪一步 可以分为以下几个步骤

a). 分配内存 b). 初始化对象 c).对象引用给变量

上面的步骤是singleton 对象正常的初始化步骤 ,但是如果出现了指令重排序的问题,比如b和c 重排序了 ,那么并发环境下别的线程可能获取到的就是未初始化完全的对象,进而导致一些无法预料的错误;

1.7 无锁线程安全的单例模式V6

class SingletonV5 {
    public static SingletonV5 singleton = new SingletonV5();

    private SingletonV5() {
        System.out.println();
    }

    public static SingletonV5 getInstance() {
        return singleton;
    }
}

在类加载的时候就预先直接加载了实例 属于提前加载

1.8 内部类的单例模式V7

class SingletonV6 {
    private SingletonV6() {
        System.out.println("SingletonV6");
    }

    public static SingletonV6 getInstance() {
        return Assist.singletonV6;
    }

    static class Assist{
        public static SingletonV6 singletonV6 = new SingletonV6();
    }
}

外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化singletonV6,故而不占内存。即当SingletonV6第一次被加载时,并不需要去加载Assist,只有当getInstance()方法第一次被调用时,才会去初始化singletonV6,第一次调用getInstance()方法会导致虚拟机加载Assist类,这种方法不仅能确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。

不管有多少线程同时访问getInstance () ,但是里面的Assist 只会加载一次 也就是实例singletonV6 只会加载一次

缺点:都是静态的无法传递初始化时需要的参数

1.9 枚举单例V8

public enum SingleTon{
  INSTANCE;
        public void method(){
        //TODO
     }
}

虚拟机层面保证的单例模式

2. 角色

在这里插入图片描述

最后

以上就是淡然溪流为你收集整理的设计模式-创建型模式-单例模式-1创建型模式-1的全部内容,希望文章能够帮你解决设计模式-创建型模式-单例模式-1创建型模式-1所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(27)

评论列表共有 0 条评论

立即
投稿
返回
顶部