- 什么是设计模式
- 设计模式的分类
- 创建型模式
- 结构型模式
- 行为型模式
- 什么是单例模式 Singleton
- 单例模式的结构
- 单例模式应用场景
- 单例模式的实现
- 懒汉模式
- 懒汉式:线程不安全
- 懒汉式:线程安全
- 懒汉式:双重检查锁
- 懒汉式:静态内部类(这个方法大大的好)
- 饿汉式
- 饿汉式特点
- 饿汉式构造方法1:静态成员变量,在声明的时候直接赋值
- 饿汉式实现2:静态代码块
- 饿汉式实现3:枚举类型
- 单例模式存在的问题
- 序列化和反序列化破坏单例模式
- 反射破坏单例模式
- 单例模式在JDK中的使用
- Runtime类
是一种编程的套路与经验,具有普遍性并可以反复使用。是面向对象设计原则的实际运用,充分体现了类的封装性,继承性多态性与组合关系的充分理解。
P.S: 也是我们程序猿进阶要学的东西
描述了怎样创建对象,特点是把对象的创建与使用进行分离,创建型模式提供了1.单例,2.原型,3.工厂方法,4.抽象工厂,建造者等五种创建型模式.
结构型模式描述如何将类或者对象组成某种更大的结构。包括代理,适配器,桥接,装饰,外观,享元,组合等结构模式
行为型模式描述类或对象之间如何协作完成单个对象无法完成的任务,以及怎样去分配职责。包括模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器等11种行为型
什么是单例模式 Singleton提供了一种创建对象的最佳方式,类创建自己的对象实例,确保单一的类只能创建单一的对象,这个类还提供了单一访问该对象的方式,可以直接访问而不用实例化。这种单例模式有利于节省内存,限制了实例的个数,有利于gc。
单例模式的结构1.单例类:指只创建一个实例的类
2.访问类:是使用单例类的类
不需要多个实例的使用场景,例如在连接池,线程池中。还有一个所有用户公用的在线人数计数器,类似于b站上的现在观看的人数。
单例模式的实现 懒汉模式类加载不会导致该实例被创建,在首次使用时才创建对象
懒汉式:线程不安全public class Singleton{ //私有的构造方法 private Singleton(){}; //声明Singleton类型的变量 private static Singleton instance; //判断该对象是否为空,为空则进行赋值 public static Singleton getInstance(){ if(instance==null){ instance = new Singleton(); } return instance; } }懒汉式:线程安全
public class Singleton{ //私有的构造方法 private Singleton(){}; //声明Singleton类型的变量 private static Singleton instance; //判断该对象是否为空,为空则进行赋值 //为避免线程不安全问题,在方法里加上synchronized锁 public static synchronized Singleton getInstance(){ if(instance==null){ instance = new Singleton(); } return instance; } }懒汉式:双重检查锁
为了避免线程安全方法中加锁所带来的的性能问题,而且getInstance()大部分都是读 *** 作,所以可以不用所有线程都持有锁。
public class Singleton{ //私有的构造方法 private Singleton(){}; //声明Singleton类型的变量 //为避免多线程的空指针问题,加volatile private static volatile Singleton instance; //判断该对象是否为空,为空则进行赋值 public static Singleton getInstance(){ //第一重检查:如果instance不为null,可直接返回对象不用加锁 if(instance==null){ //同步代码块,对字节码加锁 synchronized(Singleton.class){ //二重检查 if(instance==null){ instance = new Singleton(); } } } return instance; } }
双重检查锁所带来的问题:多线程时的空指针警告!解决方法:在声明对象时增加volatile关键字
懒汉式:静态内部类(这个方法大大的好)public class Singleton{ //私有的构造方法 private Singleton(){}; //在静态内部类SingletonHolder中创建实例 private static class SingletonHolder{ private static final Singleton INSTANCE = new Singleton(); } //外部访问该对象的方法 public static Singleton getInstance(){ //返回的是内部类中的实例 return Singleton.INSTANCE; } }
在加载Singleton类是不会初始化INSTANCE,只有调用了getInstance()方法时才会在加载内部类SingletonHolder时初始化INSTANCE。该方法在开源项目中常用,没有使用任何锁,既保证了多线程安全,又没有性能影响与空间浪费。
饿汉式类加载时就创建了对象实例,静态成员变量。
饿汉式特点1.私有的构造方法
2.在本类中创建本类的对象
3.提供公共的访问方式让外界获取该对象
4.缺陷是类加载时就创建了对象实例,如果一直未使用该对象且比较大时,会造成内存的浪费
//饿汉式:静态成员变量 public class Singleton{ //私有构造方法 private Singleton(){}; //在类中创建对象 private static Singleton instance = new Sigleton(); //外界对该对象的访问方式 public static Singleton getInstance(){ return instance; } }饿汉式实现2:静态代码块
//饿汉式:静态代码块 public class Singleton{ //私有构造方法 private Singleton(){}; //声明Singleton类型的变量 private static Singleton instance; //再在静态代码块中对该变量赋值 static{ instance = new Singleton; } //对外提供该类对象的访问方法 public static Singleton getInstance(){ return instance; } }饿汉式实现3:枚举类型
//饿汉式:枚举类型 public enum Singleton{ INSTANCE; }
完全线程安全,不会被破坏
单例模式存在的问题单例模式的破坏:指通过某种方法使Singleton可以创建多个对象。
序列化和反序列化破坏单例模式解决方法:在Singleton中添加一个readResolve方法,在反序列化中被调用。当进行反序列化中,会自动调用该方法会自动返回。
方法原理: 在源码中定义了如果有readResolve()方法,就会调用该方法的值,如果没有定义就会返回new的对象
通过反射创建两次对象创建的不是同一个对象
解决方法:添加一个flag来判断是否是第一次创建,如果是第二次创建就抛出异常
Runtime类是通过饿汉式中的静态成员变量直接赋值实现的
public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } private Runtime() {} ... }
如何使用Runtime类:直接通过Runtime中的getRuntime()来访问而不是new一个。
public class RuntimeDemo { public static void main(String[] args) throws IOException { //获取Runtime类对象 Runtime runtime = Runtime.getRuntime(); //返回 Java 虚拟机中的内存总量。 System.out.println(runtime.totalMemory()); //返回 Java 虚拟机试图使用的最大内存量。 System.out.println(runtime.maxMemory()); //创建一个新的进程执行指定的字符串命令,返回进程对象 Process process = runtime.exec("ipconfig"); //获取命令执行后的结果,通过输入流获取 InputStream inputStream = process.getInputStream(); byte[] arr = new byte[1024 * 1024* 100]; int b = inputStream.read(arr); System.out.println(new String(arr,0,b,"gbk")); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)