设计模式(一)-单例

一、前言

1.单例模式

保证一个类只有一个实例。
常见的应用场景:线程池,方便对池中的线程进行管理

2.单例优缺点:

优点
①在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例
②单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
③提供了对唯一实例的受控访问。
④由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。
⑤允许可变数目的实例。
⑥避免对共享资源的多重占用。
缺点:
①不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
②由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
③单例类的职责过重,在一定程度上违背了“单一职责原则”。
④滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢

二、饿汉式单例 --立即加载

/**
 * 饿汉式单例
 * 初始化时就已经实例化对象了
 * 缺点:一初始化就会实例静态变量,JVM方法区就会为变量分配内存,GC并不会回收,直到类被卸载时静态变量被摧毁才会回收
 * 线程天生安全
 */
public class HungrySingleton {
    //保证只有一个实例
    private static final HungrySingleton hungrySingleton = new HungrySingleton();

    //构造函数私有化
    private HungrySingleton() {
        System.out.println("饿汉式构造函数初始化");
    }
    //获取对象
    public  static  HungrySingleton getInstance(){
        return  hungrySingleton;
    }

}

三、懒汉式单例–延迟加载

/**
 * 懒汉式单例
 * 调用者需要时才实例化对象
 * 懒汉式单例本身线程不安全
 */
public class LazySingleton {
    private static LazySingleton lazySingleton;

    private LazySingleton() {
        System.out.println("懒汉式构造函数初始化");
    }

    //synchronized 目的为了解决线程不安全问题,但是因为它是悲观锁,线程会阻塞,浪费资源
    public synchronized static LazySingleton getInstance() {
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

四、静态内部类

优势:兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。
劣势:需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久代的对象(在Java 8中,永久代被彻底移除,取而代之的是另一块与堆不相连的本地内存——元空间)。

/**
 * 静态内部类
 */
public class StaticSingleton {
    private StaticSingleton(){
        System.out.println("静态内部类初始化");
    }
    public static  class  SingletonClassInstance{
        private static  final StaticSingleton staticSingleton = new StaticSingleton();
    }
    public static StaticSingleton getInstance(){
        return  SingletonClassInstance.staticSingleton;
    }
}

五、枚举–线程安全

优点:实现简单、枚举本身就是单例,由JVM从根本上提供保障!避免通过反射和反序列化的漏洞 缺点没有延迟加载

/**
 * 枚举
 */
public class Demo4 {
    private static enum EnumSingleton {
        INSTANCE;
        private Demo4 demo4;

        private EnumSingleton() {
            demo4 = new Demo4();
            System.out.println("枚举单例初始化");
        }

        public Demo4 getInstance() {
            return demo4;
        }
    }

    public static Demo4 getInstance() {
        return EnumSingleton.INSTANCE.getInstance();
    }
}

六、双重检测锁

public class SingletonDemo04 {
	private SingletonDemo04 singletonDemo04;

	private SingletonDemo04() {

	}

	public SingletonDemo04 getInstance() {
		if (singletonDemo04 == null) {
			synchronized (this) {
				if (singletonDemo04 == null) {
					singletonDemo04 = new SingletonDemo04();
				}
			}
		}
		return singletonDemo04;
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值