Java设计模式--单例模式
声明:本文根据慕课网汤小洋老师的精品课程整理来的:慕课网
什么是设计模式(Design Pattern)?
设计模式是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结。
什么情况下使用单例模式?
有些对象我们只需要一个,比如:配置文件,工具类,线程池,缓存,日志对象等,这种情况下我们要保证整个应用中某个实例有且仅有一个,如果创造出多个实例就会导致很多问题,比如:占用很多资源,结果不一致等。
单例模式的作用?
保证整个应用程序中某个实例有且仅有一个。
单例模式类型有几种?
1.饿汉模式
2.懒汉模式
单例模式之饿汉模式的实现方式?
1.将构造方法私有化,不允许外界直接构造对象。
2.创建类的唯一实例,使用private static修饰。
3.提供一个用于获取实例的方法,使用public static修饰。
特点:在加载的时候就产生实例对象。
1 public class Singleton { 2 //1.将构造方法私有化,不允许外界直接构造对象。 3 private Singleton(){ 4 5 } 6 //2.创建类的唯一实例,使用private static修饰 7 private static Singleton instance = new Singleton(); 8 9 //3.提供一个用于获取实例的方法,使用public static修饰 10 public static Singleton getInstance(){ 11 return instance; 12 } 13 }
多线程测试饿汉模式:
1 /** 2 * 多线程测试单例模式--饿汉模式 3 * @author Administrator 4 * 5 */ 6 public class Test2 { 7 8 public static void main(String[] args) { 9 for (int i = 0; i < 20; i++) { 10 new Thread(()->{ 11 Singleton singleton = Singleton.getInstance(); 12 System.out.println(singleton); 13 }).start(); 14 } 15 } 16 17 }
测试结果:
单例模式之懒汉模式的实现方式?
1.将构造方法私有化,不允许外界直接构造对象。
2.声明类的唯一实例,使用private static修饰。
3.提供一个用于获取实例的方法,使用public static修饰。
1 public class Singleton2 { 2 3 //1.将构造方法私有化,不允许外边直接创建对象 4 private Singleton2(){ 5 6 } 7 //2.声明类的唯一实例,使用private static修饰 8 private static Singleton2 instance; 9 //3.提供一个用于获取实例的方法,使用public static修饰 10 public static Singleton2 getInstance(){ 11 if(instance == null){ 12 instance = new Singleton2(); 13 } 14 return instance; 15 } 16 }
饿汉模式和懒汉模式的区别?
饿汉模式的特点是:加载类时比较慢,因为在加载类时就创建对象,但运行时获取对象的速度比较快,因为对象已经创建好了,线程安全。
懒汉模式的特点是:加载类时比较快,因为在加载类时只是声明对象,但运行时获取对象的速度比较慢,因为要创建对象,线程不安全。
懒汉模式保证安全性的实现方法--DCL?
使用synchronized关键字修饰获取实例的方法代码块,在代码块中重新判断实例是否为空。
/** * 单例模式(懒汉模式)--使用DCL保证线程安全 * DCL:double-check-locking * @author Administrator * */ public class Singleton3 { //1.将构造方法私有化,不允许外边直接创建对象 private Singleton3(){ } //2.声明类的唯一实例,使用private static修饰 private static Singleton3 instance; //3.提供一个用于获取实例的方法, //使用synchronized关键字修饰获取实例的代码块, //并重新判断实例是否为空 public static Singleton3 getInstance(){ if(instance == null){ synchronized(Singleton3.class){ if(null == instance) instance = new Singleton3(); } } return instance; } }
一种广泛的单例模式,结合饿汉模式和懒汉模式。
使用静态代码块的方式实现。
1 /** 2 * 通过静态代码块实现懒加载 3 * 比较广泛的一种单例模式 4 * @author Administrator 5 * 6 */ 7 public class SingletonHolder { 8 private SingletonHolder(){ 9 10 } 11 //在加载内部类的时候,instance不会实例化,之后当调用Holder.instance的时候,才会实例化SingletonHolder 12 private static class Holder{ 13 private static SingletonHolder instance = new SingletonHolder(); 14 } 15 16 public SingletonHolder getInstance(){ 17 return Holder.instance; 18 } 19 }
使用枚举类型作为内部类进行单例模式的实现:
1 /** 2 * 通过使用内部枚举类来进行实例化 3 * @author Administrator 4 * 5 */ 6 public class SingletonEnum01 { 7 //私有构造方法 8 private SingletonEnum01(){ 9 10 } 11 //构造内部枚举类,具有延迟加载的特性 12 private enum EnumHolder{ 13 //声明的变量在加载的时候自动加载一次,类型为SingletonEnum 14 INSTANCE; 15 private SingletonEnum01 instance; 16 EnumHolder(){ 17 this.instance = new SingletonEnum01(); 18 } 19 //构造私有访问方法 20 private SingletonEnum01 getInstance(){ 21 return instance; 22 } 23 } 24 //创建静态外部访问方法 25 public static SingletonEnum01 getInstance(){ 26 return EnumHolder.INSTANCE.getInstance(); 27 } 28 }