单例模式

在这里插入图片描述
饿汉式一般用这两种,一种静态常量一种静态代码块
优点:线程安全
缺点:类似于立即加载没有延迟加载,所以会造成内存资源的浪费,因为这两种方案都是通过类加载的时候进行创建对象的,而类加载的方法有很多种

这里插一点题外话,类加载有哪几种,一种就是我们熟悉的静态方法或者静态域被调用,还有就是对象的创建,也就是对象的实例化,类会被加载,还有一种就是java编程思想中提到的继承,继承的话类加载器会先加载其.class文件,然后如果发现基类,还会去加载其基类,也就是其父类也会被加载,比如下图
在这里插入图片描述
我们在main方法中只用了man m=new man(),说明了其类加载的顺序,如果继承的话,先加载父类,因为我们父类的构造方法和静态代码块被调用了,其实构造方法默认就是static的,所以也会被加载

这里还可以复习一下final关键字:final关键字如果修饰变量的话可以赋初值,但是以后就不能赋值了,如果修饰对象的引用的话,这个引用是不能够改变的,对象却是可以变的,如果修饰传入的参数的话,也是不可变的,如果是修饰方法的话,是不能被继承的等等,final static 修饰的就是一段固定不变的存储空间

懒汉式:
第一种,同步方法的方式实现
在这里插入图片描述
优点:线程安全
缺点:效率太低了,为什么低就是因为如果我们已经创建好了对象,我们就不需要每次都被判断是否等于null了直接返回就好了

第二种方法:双重检查的方法,通过两个判断是否为空来解决
在这里插入图片描述
这里涉及到volatile关键字和synchronized的关键字,volatile就相当于可见,按照我自己目前的理解,就是线程的话,有一个主内存,还有一个工作内存,那么如果我们其中一个线程要进行修改值的话,它可能会在一个副本里面写,不会立即写回到主内存里面,那么我们加上这个关键字volatile的话,就相当于可见了,保证了其原子性,就是相当于每次修改值立即写到主内存当中.
synchronized就是锁机制,对象就是锁,锁即是对象,所以我们可以利用其他对象进行锁,也可以通过自己this这个锁,但是要注意的是static方法的时候,我们不可能用对象锁,因为static的调用不需要对象,所以我们就用其类.class进行上锁处理,在jdk1.7以后该锁被优化了很多,所以这个推荐使用
回到这种设计模式,其实通过两层判断是否为空来进行操作,在里面锁的话大大提高了效率,推荐使用,因为如果有两个线程都执行进去的话,那么通过volatile关键字可见性,一个线程进行创建,另一个线程就知道了该对象已经被创建好了,那么就不需要接下来的判断了,直接返回对象,一方面这种方法保证了线程安全,也起到了延迟加载,所以推荐使用
第三种方法,静态内部类的方式进行实现
在这里插入图片描述
因为静态内部类加载只在我们getsingleton5这个方法进行调用的时候才会进行初始化,所以也起到了延迟加载的效果,同时保证了线程的安全问题
第四种方法:枚举方法,这个方法也是一些大佬推荐使用的方法,
在这里插入图片描述

通过枚举实现单例

总结,一般情况下,单例保证了该类只存在一个对象,节约了资源,一般用于频繁使用获取的地方,比如我们用的工具类可以用单例模式进行设计,还有就是数据源呀,session工厂这种创建对象耗费时间资源比较多的对象,这样设计会有很大的好处

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值