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

java 设计模式--单例模式

作者: superHang | 来源:发表于2020-04-14 16:35 被阅读0次

    单列模式就是一个类当中创建一个实例,不能在类的外部new 出来,只能在类的内部中创建,就像中世纪那些欧洲的贵族女儿不外嫁,自产自销
    好处:
    1.间少内存开销
    就像一个村子中家家户户都要喝水,但是不必每个人都个人家里都去挖一口井吧
    2.方便控制
    就像WEB 开发,增删查改这些操作都会写一个公告的dao,不需要每个人都自己写一套,控制方便呀

    创建单例模式的方法

    1.内部的构建函数私有化,不允许通过构建函数new 出来实例
    2.在类的内部创建实例
    3.提供获取唯一实例的方法

    常见的单例模式

    1.饿汉式
    饿汉模式的意思是,我先把对象(面包)创建好,等我要用(吃)的直接直接来拿就行了。

    public class Singleton {
    
    //先把对象创建好
    private static final Singleton singleton = new Singleton();
    //构造函数私有化
     private Singleton() {
        }
     
    //其他人来拿的时候直接返回已创建好的对象
    public static Singleton getInstance() {
     return singleton;
        }
    }
    

    2.懒汉式
    懒汉模式的意思是,我先不创建类的对象实例,等你需要的时候我再创建。

    public class Singleton {
    //先不创建实例
     private static Singleton singleton = null;
    //构造函数私有化
     private Singleton() {
       }
      //获取对象的时候再进行实例化
     public static Singleton getInstance() {
        //加锁,防止多个线程进来,都会判断为null 然后都会创建多个实列,所以要加锁,进行同步操作
         synchronized (Singleton.class) {
        if (singleton == null) {
            singleton = new Singleton();
                }
       }
        return singleton;
        }
    }
    

    3.双重检测模式
    懒汉模式因为加锁了,每个线程进来都会锁住了,即使这个线程的实例已经存在了还被锁住,这就不应该了哈,所以再加一层判断不就好了

    ...
    public static Singleton getInstance() {
    
    if (singleton == null) {//先验证对象是否创建,已经创建了直接返回
    synchronized (Singleton.class) {//只有当对象未创建的时候才上锁
    if (singleton == null) {
      singleton = new Singleton();
    }
    }
    }
    return singleton;
    }
    
    

    4.静态内部类懒汉式

    public class Singleton {
    
     private Singleton() {
        }
    
     public static Singleton getInstance() {
           return SingletonHoler.singleton;
        }
    
     //定义静态内部类
     private static class SingletonHoler {
         //当内部类第一次访问时,创建对象实例
                 private static Singleton singleton = new Singleton();
        }
    }
    

    当外部去访问这个单例的类的时候,静态内部类是不会初始化的,就保证了资源不会被浪费,只有当SingletonHoler 方法被调用的时候才会去初始化这个类
    为什么静态内部类线程安全:
    JVM虚拟机会保证一个类的构造器<clinit>()方法在多线程环境中被正确地加载,同步,如果多个线程同时去初始化一个类,那么只有一个线程去执行这个类的构造器<clinit>()方法,其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。

    相关文章

      网友评论

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

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