一.前言
1.概念
单例模式(Singleton Pattern
)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式。简单来说保证在内存中有给定数量的对象,例如内存中产生唯一一个对象,不管创建多少次,也只有唯一的对象。
2.用途
因为单例模式只创建了一个对象,所以能够节约系统资源,减少性能开销,提高系统效率,同时也能够严格控制客户对它的访问,避免对资源的多次占用。
3.分析
3.1防止外界创建对象
Car c = new car();
我们可以将构造器隐藏起来,防止外界调用。
3.2.只在初始化时创建一次对象
static: 类加载的时候只初始化一次。
在method方法区,在类加载器加载(Car.class文件),进入内存的时候,会初始化这块空间。
二.懒汉模式
1.概念
懒汉模式表示很懒,能不干就不干;所以它在类加载的同时不会创建实例对象;直到第一次去使用的时候,才会创建实例对象。
简单来说,就是用时间换取装载的空间
2.懒汉模式的并发问题
通过测试类我们可以判定循环了10次,但是只创建了一个对象
缺点:如果instance引用没有绑定任何对象,在多线程情况下切换比较快时,两个任务同时判定为空,则会同时创建对象
写一个线程代码模拟测试
3.加上synchronized锁解决线程安全问题
t1和t2两个同时进入时,只有一个人可以拿到对象锁(synchronized)的钥匙,因此只有一个方法可以进入,实现单例模式,保证了数据安全。
4.使用ReentrantLock锁(可重入锁)
在java1.5版本后不推荐使用synchronized锁,因此使用ReentrantLock锁
在进行多线程开发中,建议多使用ReentrantLock锁。
优点:可重入锁,力度更小,可以对某几行代码进行处理,如果出现异常,可以对代码进行释放。
三.饿汉模式
1.概念
饿汉模式是一种常见的Java单例实现方式,其特点是在类加载时就创建了唯一的实例对象,并且在整个程序运行期间都只有这一个实例。
2.用法
在jvm的运行规则中,在类加载的时候,会率先对静态代码块进行初始化,在初始化的同时会自然进行隔离,不允许其他线程进入,保证了线程的安全性。
测试
3.缺点
在多个jvm时,比如分布式的情况下,互相调用类加载时,可能会出现多个对象,但是一般不会放在多个服务器下。
在运行的开始就已经开始创建对象了,无论用或不用。但是懒汉模式是在使用时才开始创建对象。相当于用空间换取时间。
四.枚举模式
1.概念
枚举模式是一种常用的单例模式实现方式,它通过枚举类型来保证只有一个实例对象被创建。
因为枚举创建的是常量对象,由jvm创建常量对象,只读不可写,保证了线程的安全。
2.用法
3.测试
五.总结
首先不管是懒汉模式还是饿汉模式,都必须将对象的构造方法进行私有化,避免外部调用时能实例化对象。懒汉模式是用时间换取空间,饿汉模式使用空间换取时间,具体如何使用,还要根据项目的实际需求出发。