单例模式的 8 种写法,整理非常全!
程序员文章站
2023-12-31 16:27:52
概念 单例模式即一个 JVM 内存中只存在一个类的对象实例。 分类 1、懒汉式 类加载的时候就创建实例 2、饿汉式 使用的时候才创建实例 当然还有其他的生成单例的方式,双重校验锁,枚举和静态内部类,文中会有介绍。 懒汉式 1) 示例1 线程不安全,不可用。 2) 示例2 同步方法,线程安全,效率低, ......
概念
单例模式即一个 jvm 内存中只存在一个类的对象实例。
分类
1、懒汉式
类加载的时候就创建实例
2、饿汉式
使用的时候才创建实例
当然还有其他的生成单例的方式,双重校验锁,枚举和静态内部类,文中会有介绍。
懒汉式
1) 示例1
public class singleton { private static singleton instance; private singleton (){} public static singleton getinstance() { if (instance == null) { instance = new singleton(); } return instance; } }
线程不安全,不可用。
2) 示例2
public class singleton { private static singleton instance; private singleton (){} public static synchronized singleton getinstance() { if (instance == null) { instance = new singleton(); } return instance; } }
同步方法,线程安全,效率低,不推荐。
3) 示例3
public class singleton { private static singleton singleton; private singleton() {} public static singleton getinstance() { if (singleton == null) { synchronized (singleton.class) { singleton = new singleton(); } } return singleton; } }
线程不安全,会产生多个实例,不可用。
饿汉式
无线程安全问题,不能延迟加载,影响系统性能。
4) 示例1
public class singleton { private static singleton instance = new singleton(); private singleton (){} public static singleton getinstance() { return instance; } }
5) 示例2
public class singleton { private static singleton instance = null; static { instance = new singleton(); } private singleton (){} public static singleton getinstance() { return instance; } }
6) 示例3
public class singleton { private static volatile singleton singleton; private singleton() {} public static singleton getinstance() { if (singleton == null) { synchronized (singleton.class) { if (singleton == null) { singleton = new singleton(); } } } return singleton; } }
双重校验锁,线程安全,推荐使用。
7) 示例4
public class singleton { private static class singletonholder { private static final singleton instance = new singleton(); } private singleton (){} public static final singleton getinstance() { return singletonholder.instance; } }
静态内部类,线程安全,主动调用时才实例化,延迟加载效率高,推荐使用。
8) 示例5
public enum singleton { instance; public void whatevermethod() { } }
注意事项
1、考虑多线程问题
2、单例类构造方法要设置为private类型禁止外界new创建
private singleton() {}
3、如果类可序列化,考虑反序列化生成多个实例问题,解决方案如下
private object readresolve() throws objectstreamexception { // instead of the object we're on, return the class variable instance return instance; }
枚举类型,无线程安全问题,避免反序列华创建新的实例,很少使用。
使用场景
1、工具类对象
2、系统中只能存在一个实例的类
3、创建频繁或又耗时耗资源且又经常用到的对象
下面是单例模式在jdk的应用
另外,spring 容器中的实例默认是单例饿汉式类型的,即容器启动时就实例化 bean 到容器中,当然也可以设置懒汉式 defalut-lazy-init="true"
为延迟实例化,用到时再实例化。
推荐去我的博客阅读更多:
2.spring mvc、spring boot、spring cloud 系列教程
3.maven、git、eclipse、intellij idea 系列工具教程
生活很美好,明天见~