创建型之设计模式-单例模式

创建型之设计模式

  • 简述
    • 一、单例模式
    • 适用场景
      • 饿汉式demo
      • 懒汉式demo

简述

设计模式类型有3种(创建型,结构型,行为型)
以下逐一列出创建型类型的设计模式:
1单例,2原型,3工厂,4抽象工厂,5构建者(创建者)模式。

一、单例模式

单例模式就是在一个jvm中只能创建一个对象;分饿汉式单例模式和懒汉式单例模式。

  • 饿汉式是加载类的时候就创建该对象。
  • 懒汉式为用的时候才创建该对象。

适用场景

spring中bean的创建默认单例模式
应用服务器有很多系统参数在服务运行期间不会改变的,可用单例创建。

饿汉式demo

  • 饿汉式单例模式,类加载的时候就实例化对象,线程安全。
  • 简单实用,推荐
  • 个人认为 不算严重的一个缺点,不管用到与否,类装载时就完成实例化
/**饿汉式   线程安全,加载类时就创建对象*/
public class Mgr01 {
    private static final Mgr01 INSTANCE=new Mgr01();//2 私有静态化常量来创建对象
    private Mgr01(){};//1私有化构造方法

    public static Mgr01 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Mgr01 m1=Mgr01.getInstance();
        Mgr01 m2=Mgr01.getInstance();
        System.out.println(m1==m2);
    }
}

懒汉式demo

demo1 方法,效率低下,不推荐

  • 解决按需初始化,线程安全
  • 特点:在方法上加同步代码块,效率低
 public class Mgr04 {
    private static Mgr04 INSTANCE;

    private Mgr04(){
        }
        public static synchronized  Mgr04 getInstance(){  //synchronized 锁定当前对象,加了static  锁定的是class对象
            if(INSTANCE==null){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                INSTANCE=new Mgr04();
            }
            return INSTANCE;

        }

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

以下为3种较好的懒汉式单例实现demo,用到时才实例化

2 双重检查,即在同步块前后分别加实例判空逻辑

  • spring容器中注册bean的获取,就是采用双重检查懒加载的单例模式;
  • 传统懒汉式单例中,被认为是最好的懒汉式单例**<后面还有两个不错的单例>**
/**懒汉式
 * 满足按需初始化,满足线程安全
 * 较好1
 * */
public class Mgr06 {
    private static volatile Mgr06 INSTANCE;//JIT
    private Mgr06(){}

    public static Mgr06 getInstance(){
        if(null==INSTANCE){
            synchronized (Mgr06.class){
                if(null==INSTANCE){//双重检查
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE=new Mgr06();
                }
            }

        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for(int i=1;i<100;i++){
            new Thread(()-> System.out.println(getInstance().hashCode())).start();
        }
    }
}

3 运用虚拟机类加载知识,懒汉式:静态内部类方式

  • 满足按需初始化,且线程安全
  • jvm保证单例,加载外部类时不加载私有静态内部类,可以实现懒加载
 public class Mgr07 {
    private Mgr07(){}

    private static class Mgr07Holder {
        private static final Mgr07 INSTANCE=new Mgr07();
    }

    public static Mgr07 getInstance(){
        return Mgr07Holder.INSTANCE;
    }

    public static void main(String[] args) {
        new Thread(()-> System.out.println(getInstance().hashCode())).start();
    }
}

4 解决线程同步,且能防止反序列化(因为枚举类没有构造方法)

  • 源自effective java 是java原作者写的一本书
  • 最优单例,可防止反序列化,线程安全
  • 饿汉式单例
public enum  Mgr08 {
    INSTANCE;

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

你可能感兴趣的:(设计模式,设计模式)