什么是设计模式?常用的设计模式有哪些?
设计模式就是经过前人无数次的实践总结出的,设计过程中可以反复使用的、可以解决特定问题的设计方法。
单例(饱汉模式、饥汉模式)
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()); } }