Java设计模式之单例模式
今天,继续开始学习单例模式,首先,单例模式是什么?为什么需要单例模式?
单例模式是什么?
单例模式指的是整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式。每一次创建新的类的时候,都调用曾经创建的那个类,这样的被称为单例模式
为什么需要单例模式
1 节省公共资源,你平时玩游戏用的wifi,我们不需要每个人都去买路由器,再去连接,而是只需要一个,然后大家都来连接这个wifi就行了。
2 方便控制管理,比如你想操作某个日志类,那么如果该日志类不是单例的,每次都创建全新的,这个日志类管理的日志就会十分混乱。
大家可以想一想,既然单例模式需要保证每一次创建或调用的都是同一个类,那么怎么去实现呢?
思路1:将构造函数私有化。这样就可以阻止对象被new(新建出来)
思路2:既然将构造函数私有化了,那么需要对外提供方法来获取对象的实例,如果不提供方法的话,那么这个对象不就一直拿不到了嘛?
思路3:实例化对象的过程只进行一次,后续对外提供对象的方法中,都引用第一次实例化的那个对象。
下面我将将单例模式分为两种情况,懒汉和饿汉去讲解。
懒汉
/**
* @describe:懒汉
* @author: jiazl/
* @version:v1.0
* 2022/3/28 10:37
*/
public class Lazy {
private static Lazy lazy = null;
private Lazy() {
}
/**
* 获取对象的时候再进行实例化
* @return
*/
public static Lazy getLazy() {
if (lazy == null) {
lazy = new Lazy();
}
return lazy;
}
}
通过阅读代码可以发现,只有当第一次懒汉的对象为null的时候,才回去调用创建的方法,之后的每一次都将直接返回上一次创建的懒汉对象。
只创建了一次对象的实例,保证每一次获取的都是相同的对象
饿汉
/**
* @describe:饿汉
* @author: jiazl/
* @version:v1.0
* 2022/3/28 10:41
*/
public class TheHungry {
/**
* 先把对象创建好
*/
private static final TheHungry theHungry = new TheHungry();
private TheHungry() {
}
/**
* 其他人来拿的时候直接返回已创建好的对象
* @return
*/
public static TheHungry getTheHungry() {
return theHungry;
}
}
提前创建好对象的实例,对外提供的获取对象的方法,都返回相同的实例
懒汉与饿汉的区别
通过代码可知,每一次饿汉都会事先创建好对象的实例,但是这就有可能造成资源的浪费,比如你你先买了路由器,都弄好了但是没人用,这就造成了资源的浪费,懒汉就避免了这个问题,只有我需要对象的实例的时候,才会去创建一个。
从线程安全性上讲,不加同步的懒汉式是线程不安全的,比如,有两个线程,一个是线程A,一个是线程B,它们同时调用getLazy方法,那就可能导致并发问题,就有可能创建两个不同的Lazy对象
解决办法
public synchronized static Lazy getLazy() {
if (lazy == null) {
lazy = new Lazy();
}
return lazy;
}
在getLazy方法前加一个synchronized关键字,这样就可以避免并发问题,才是真正的单例模式。