单例模式(Singleton)分析

单例模式即一个JVM内存中只存在一个类的对象实例,并提供一个访问它的全局访问点。
在这里插入图片描述

分类

1、懒汉式
类加载的时候就创建实例
2、饿汉式
使用的时候才创建实例
3、当然还有其他的生成单例的方式,双重校验锁,枚举和静态内部类

懒汉式

  1. 线程不安全,不可用
public class Singleton { 
     private static Singleton instance; 
     private Singleton (){} 
  
     public static Singleton getInstance() { 
     if (instance == null) { 
         instance = new Singleton(); 
     } 
     return instance; 
     } 
}
  1. 线程安全,同步方法,效率低,不推荐
public class Singleton { 
     private static Singleton instance; 
     private Singleton (){} 
     public static synchronized Singleton getInstance() { 
     if (instance == null) { 
         instance = new Singleton(); 
     } 
     return instance; 
     } 
}
  1. 线程不安全,会产生多个实例,不可用
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.

public class Singleton { 
    private static Singleton instance = new Singleton(); 
    private Singleton (){} 
    public static Singleton getInstance() { 
    	return instance; 
    } 
}
public class Singleton { 
     private static Singleton instance = null; 
     static { 
 		instance = new Singleton(); 
     } 
     private Singleton (){} 
     public static Singleton getInstance() { 
  		return instance; 
     } 
}
  1. 双重校验锁,线程安全,推荐使用
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;
    }
}
  1. 静态内部类,线程安全,主动调用时才实例化,延迟加载效率高,推荐使用
public class Singleton { 
    private static class SingletonHolder { 
  		private static final Singleton INSTANCE = new Singleton(); 
    } 
    private Singleton (){} 
    public static final Singleton getInstance() { 
  		return SingletonHolder.INSTANCE; 
    } 
}
  1. 枚举类型,无线程安全问题,避免反序列华创建新的实例,很少使用
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"为延迟实例化,用到时再实例化。

彩蛋

欢迎加入请求群学习交流:
Java/Python架构师①群:415777345
电脑PC用户快捷加入(点击超链接):415777345
手机QQ扫码加入:
在这里插入图片描述
SpringBoot SpringCloud Docker K8s ①群:317945902
电脑PC用户快捷加入(点击超链接):317945902
手机QQ扫码加入:
在这里插入图片描述
欢迎进群交流探讨!

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值