单例模式
单例模式的主要思想是如果一个程序中有一个对象只需要唯一的一个,同时该对象可以被程序所共享,则可以使用单例模式来维护该对象。
因此单例模式类需要满足以下特点。
- 不允许其他地方new 该对象,需要将构造函数设为私有
- 在本类中new 该对象,此对象为唯一对象
- 对外提供接口访问和操作该对象
这里以企业公章为背景,企业的公章经常需要被使用,但是实际上企业的公章一般情况下是唯一的。
饿汉式单例模式
饿汉式单例模式在程序启动时完成单例对象初始化。这导致过多的单例对象会拖慢程序的启动速度,并且会持续占用内存(这部分内存大部分情况下可以忽略不记)
饿汉式的具体类实现
@Data
public class OfficialSeal {
public String action="盖章";
//饿汉式,在程序启动时完成单例对象初始化,过多的单例对象会拖慢程序的启动速度,
private static OfficialSeal officialSeal=new OfficialSeal();
//构造函数私有
private OfficialSeal(){};
//开放获取单例接口
public static OfficialSeal getInstace()
{
return officialSeal;
}
public void Action()
{
System.out.println("盖章");
}
}
模拟公司盖章场景
@Test
public void hungryHan()
{
//获取公章实例
OfficialSeal instance = OfficialSeal.getInstace();
System.out.println(instance.getAction());
instance.Action();
}
运行获得结果
盖章
盖章
懒汉式单例模式
懒汉式单例模式指在单例对象真正需要使用的时候再创建单例对象,而不是直接创建单例对象,关于懒汉式的单例模式实现有多种,这里介绍双重校验锁实现的线程安全的懒汉式单例模式
@Data
public class LazyOfficialSeal {
public String action = "盖章";
//懒汉式,使用时再创建实例对象,双重校验锁保证线程安全
private static LazyOfficialSeal lazyOfficialSeal = null;
//构造函数私有
private LazyOfficialSeal() {
}
//开放获取单例接口
public static LazyOfficialSeal getInstace() {
//双重校验,第一层防止线程频繁的触发synchronized等待影响效率
if (lazyOfficialSeal == null) {
synchronized (LazyOfficialSeal.class) {
//第二层防止线程不安全创建多个对象
if(lazyOfficialSeal==null) {
lazyOfficialSeal = new LazyOfficialSeal();
}
}
}
return lazyOfficialSeal;
}
public void Action() {
System.out.println("盖章");
}
}
懒汉式单例模式测试
@Test
public void LazyHungryHan()
{
//获取公章实例
LazyOfficialSeal instance = LazyOfficialSeal.getInstace();
System.out.println(instance.getAction());
instance.Action();
}
测试结果:
盖章
盖章