单例模式

概述

     单例模式:顾名思义,当前类的对象在系统中只有一个,因此节省了资源,也免去频繁创建对象的过程。

使用场景:

1、创建对象成本较高,且需要频繁使用的对象。比如系统中的字典工具类,频繁创建不仅有网络传输成本还有IO成本,频繁创建和销毁对于系统而言开销是比较大的。

2、频繁访问数据库或者文件的对象。

3、系统中的全局计数器

4、多线程应用的线程池工具类

5、Web应用中读取配置的工具类对象

实现方式:

1、常用的饿汉式的实现方式:

        这是我们工作中最常用的一种实现方式,第一编码简单,第二线程安全(由JVM来保证),有以下三个特点:a-私有静态的全局常量 b-私有的构造方法  c-公有的全局访问点

public class Singleton {
	
	private static final Singleton INSTANCE = new Singleton();
	
	private Singleton() {}
	
	public static Singleton getInstance() {
		return INSTANCE;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 100000; i++) {
			new Thread(() -> System.out.println(Singleton.getInstance())).start();
		}
	}
}

2、懒汉式的实现方式:

        这种实现方式编码还是比较复杂的,因为需要主要的细节比较多,这里列举一下:a-私有的静态变量需要用volatile修饰,原因(https://blog.csdn.net/jinyouxinzao/article/details/108245039),否则多线程的场景下会出现半初始化状态的对象; b-需要双重检查,第一重的检查是为了避免锁竞争,第二重检查是为了重复创建对象。

public class LazySingleton {
	
	// 注意一定要加上volatile,否则万一遇上了指令重排,会读取到半初始化状态的对象
	private static volatile LazySingleton INSTANCE = null;
	
	private LazySingleton() {}
	
	public static LazySingleton getInstance() {
		// 这一步的判断是为了避免锁竞争
		if (INSTANCE == null) {
			synchronized(LazySingleton.class) {
				if (INSTANCE == null) {
					INSTANCE = new LazySingleton();
				}
			}
		}
		return INSTANCE;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 100000; i++) {
			new Thread(() -> System.out.println(LazySingleton.getInstance())).start();
		}
	}
}

3、静态内部类的方式

public class StaSingleton {
	
	private StaSingleton() {}
	
	private static class Singleton{
		static final StaSingleton instance = new StaSingleton();
	}
	
	public static StaSingleton getInstance() {
		return Singleton.instance;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 100000; i++) {
			new Thread(() -> System.out.println(StaSingleton.getInstance())).start();
		}
	}
}

4、枚举单例

       这种方式出自神作《effective java》,是一种高逼格的实现方式,让我真正的见识到了大神是怎样写代码的,这种方式有前面几种方式都无法比拟的几个特点:

    4.1 代码空前的简洁

    4.2 可以防止个别杠精通过反射来创建对象

    4.3 可以防止个别杠精通过反序列化的方式操作对象

    以下是枚举单例的代码:

public enum Singleton {
    
    INSTANCE;
    
    public static void main(String[] args) {
        for (int i = 0; i < 10000; i++) {
            new Thread(()->System.out.println(Singleton.INSTANCE.hashCode())).start(); 
        }
    }
    
}

    

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值