详解Java中的八种单例创建方式
作者:温故知新之java
单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。本文将详细介绍Java中单例的八种创建方式,需要的可以参考一下
定义
单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)
使用场景
- 对于一些需要频繁创建销毁的对象
- 重量级的对象
- 经常使用到的对象
- 工具类对象
- 数据源
- session
单例模式八种方式
饿汉式(静态常量)
代码
/** * 饿汉式(静态常量) * 优势:简单,避免多线程的同步问题 * 劣势:无懒加载,内存浪费 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton1 { // 私有化构造方法 private Singleton1(){} // 静态常量 private static final Singleton1 singleton1 = new Singleton1(); // 对外提供公共方法 public static Singleton1 getSingleton1(){ return singleton1; } }
分析
- 优势:简单,避免多线程的同步问题
- 劣势:无懒加载,内存浪费
饿汉式(静态代码块)
代码
/** * 饿汉式(静态代码块) * 优势:简单,避免多线程的同步问题 * 劣势:无懒加载,内存浪费 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton2 { // 私有化构造方法 private Singleton2(){} private static final Singleton2 singleton2; // 静态代码块 static { singleton2 = new Singleton2(); } // 对外提供公共方法 public static Singleton2 getSingleton2(){ return singleton2; } }
分析
- 优势:简单,避免多线程的同步问题
- 劣势:无懒加载,内存浪费
懒汉式(线程不安全)
代码
/** * 懒汉式(线程不安全) * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton3 { // 私有化构造方法 private Singleton3(){} // 内部属性 private static Singleton3 singleton3; // 对外提供公共方法 public static Singleton3 getSingletons(){ if(singleton3 == null){ singleton3 = new Singleton3(); } return singleton3; } }
分析
- 优势:起到了懒加载的效果 不会造成内存浪费
- 劣势:线程不安全 不推荐这种方式的
懒汉式(同步方法)
代码
/** * 懒汉式(同步方法) * 优势:解决了线程同步问题 * 劣势:使用synchronized同步关键字,性能太低 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton4 { // 私有化构造方法 private Singleton4(){} // 内部属性 private static Singleton4 singleton4; // 对外提供公共方法 public static synchronized Singleton4 getSingleton4(){ if(singleton4 == null){ singleton4 = new Singleton4(); } return singleton4; } }
分析
- 优势:解决了线程安全问题,
- 劣势:效率太低
懒汉式(同步代码块)
代码
/** * 懒汉式(同步代码块) * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton5 { // 私有化构造方法 private Singleton5(){} // 内部属性 private static Singleton5 singleton5; // 对外提供公共方法 public static Singleton5 getSingleton5(){ if (singleton5 == null){ synchronized (Singleton5.class){ singleton5 = new Singleton5(); } } return singleton5; } }
分析
- 优势:起到了懒加载的效果 不会造成内存浪费
- 劣势:线程不安全 不推荐这种方式的
双重检查锁方式
代码
/** * 双重检查锁机制 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton6 { // 私有化构造方法 private Singleton6(){} // 内部属性 private volatile static Singleton6 singleton6; // 对外提供公共方法 public static Singleton6 getSingleton6(){ if (singleton6 == null){ synchronized (Singleton6.class){ if(singleton6 == null){ singleton6 = new Singleton6(); } } } return singleton6; } }
分析
- 实现了懒加载,效率很高,解决了线程安全
静态内部类方式
代码
/** * 静态内部类 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ public class Singleton7 { // 私有化构造方法 private Singleton7(){} // 内部类 private static class SingleInstance{ public static final Singleton7 singleton7 = new Singleton7(); } // 对外提供公共方法 public static Singleton7 getSingleton7(){ return SingleInstance.singleton7; } }
分析
- 不会出现线程安全问题 JVM来帮我们保证了线程的安全性
- 利用静态内部类的特点,效率也很高,
- 实际开发中推荐使用的
枚举方式
代码
定义单例对象
/** * @desc: * @author:liyajie * @createTime:2022/2/11 10:25 * @version:1.0 */ public class Singleton { public void hello(){ System.out.println("hello"); } }
定义枚举实例化单例对象
/** * 枚举方式 * @author:liyajie * @createTime:2022/2/10 15:50 * @version:1.0 */ enum Singleton8 { // 相当于public static final Singleton8 INSTANCE; // 保证了枚举实例只能被实例化一次 INSTANCE; // 定义单例变量 private Singleton singleton; // 枚举构造方法,该构造方法是private,执行构造方法的时候,同时创建我们的单例对象 Singleton8() { singleton = new Singleton(); } // 对外提供公共方法 public Singleton getSingleton() { return singleton; } }
使用方法Singleton8.INSTANCE.getSingleton()即可获取我们的单例对象了
分析
- 简单,避免了线程安全问题
- 实际开发中推荐使用的
总结
1.单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象, 使用单例模式可以提高系统性能
2.当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new
3.单例模式推荐使用的方法有内部静态类方式和枚举方式
到此这篇关于详解Java中的八种单例创建方式的文章就介绍到这了,更多相关Java单例创建方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!