什么是设计模式?常用的设计模式有哪些?

设计模式就是经过前人无数次的实践总结出的,设计过程中可以反复使用的、可以解决特定问题的设计方法。

单例(饱汉模式、饥汉模式)

1、构造方法私有化,让出了自己类中能创建外其他地方都不能创建

2、在自己的类中创建一个单实例(饱汉模式是一出来就创建创建单实例,而饥汉模式需要的时候才创建

3、提供一个方法获取该实例对象(创建时需要进行方法同步)

工厂模式:Spring IOC就是使用了工厂模式.

       对象的创建交给一个工厂去创建。

代理模式:Spring AOP就是使用的动态代理。

 

单例设计模式精讲

定义:保证一个类只有一个实例,并且提供一个全局访问点

场景:线程池,数据库连接池

实现方式:   1.懒汉模式(只有使用的时候,再进行初始化,延迟加载)

      2.饿汉模式

      3.静态内部类

      4.反射攻击

      6.序列化

      7.jdk源码

1.懒汉模式实现的写法

public class SingletonTest {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                LazySingleton lazySingleton = LazySingleton.getInstance();
                System.out.println(lazySingleton);
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                LazySingleton lazySingleton = LazySingleton.getInstance();
                System.out.println(lazySingleton);
            }
        }).start();
        //两个线程打印出来的线程实例是同一个,说明是单例
    }
}
//使用的时候才开始实例化,JVM中一个实例
class LazySingleton {
    private volatile static LazySingleton instance;

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

    private LazySingleton() {
    }

}

 2.饿汉模式

在类加载阶段完成了实例的初始化,通过类加载机制来保证线程的安全

       类的加载过程

      1加载=》加载对应的二进制文件,并且在方法区创建对应的数据结构

       连接 :a.验证  b.准备  c.解析

       初始化:给静态属性赋值

public class HungrySingletonTest {
    public static void main(String[] args) {
        HungrySingleton hungrySingleton = HungrySingleton.getInstance();
    }
}

class HungrySingleton {
    private static HungrySingleton instance = new HungrySingleton();
    public static HungrySingleton getInstance() {
        return instance;
    }
    private HungrySingleton() { }
}

 3.基于静态内部类的单例

public class AntiTest {
    public static void main(String[] args) throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, InstantiationException{
        InnerClassSingleton instance = InnerClassSingleton.getInstance();
        System.out.println(instance);
        
        //抛出异常,单例,不允许有多个实例
        Constructor<InnerClassSingleton>   declaredConstructor  = InnerClassSingleton.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        InnerClassSingleton innerClassSingleton = declaredConstructor.newInstance();
        System.out.println(innerClassSingleton);
    }
}

class InnerClassSingleton{

    static class InnerClass{
        private static InnerClassSingleton instance = new InnerClassSingleton();
    }
    public static InnerClassSingleton getInstance(){
        return InnerClass.instance;
    }
    private InnerClassSingleton(){
        if ((InnerClass.instance!=null)){
            throw new RuntimeException("单例类,不允许多个实例!");
        }
    }
}

 4.枚举单例

public class EnumSingletonTest{
    public static void main(String[] args) {
        EnumSingleton instance = EnumSingleton.INSTANCE;
        EnumSingleton instance1 = EnumSingleton.INSTANCE;
        System.out.println(instance==instance1);//true
        instance.print();//        149928006
        instance1.print();//        149928006
    }
}
enum EnumSingleton {
    INSTANCE;
    public void print(){
        System.out.println(this.hashCode());
    }
}

 

posted @ 2020-12-22 17:29  海绵-宝宝  阅读(793)  评论(0编辑  收藏  举报