单例设计模式 java实现
(一)单例设计模式
单例设计模式(Singleton Pattern) 确保某个类中只有一个实例,而且这个类是不能被实例化的,也就是不能用new 关键字来创建对象,该类提供了公共静态的方法,用于返回该类对象,不需要自行实例化。而单例模式有分为饿汉式,以及懒汉式。
特点
- 一个类有且仅有一个实例,有一个私有静态变量指向自己
- 构造器需私有化,且无参数
- 必须提供公有方法用于获取对象
饿汉式代码体现
饿汉式在类加载时候就完成了对象的实例化
优点:写法简便,因为是类加载时完成的实例化,不存在线程安全问题。
缺点:正因为是在类加载时完成的初始化,如果从来没有使用这个对象,在加载该类时候也会被实例化,会造成内存资源的浪费
//饿汉式单例
public class IdCard {
//在类加载的时候同时初始化对象
private static final IdCard idCard = new IdCard();
//构造器私有化
private IdCard() {
// 构造器中打印被实例化语句 时机:类加载时 有且仅有一次
System.out.println("idCard, 我被实例化了");
}
// 静态获取实例的方法
public static IdCard getIdCard() {
return idCard;
}
}
懒汉式代码体现
懒汉式,和它的名字一样,它很懒,如果你不用它,它就不会实例化,起到了懒加载(Lazy Loading)的效果。但是在多线程的情况下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。
优点:不会造成内存资源的浪费。
缺点:在多线程的情况下有线程安全问题
//懒汉式单例
public class IdCard2 {
private static IdCard2 idCard;
//构造器私有化
private IdCard2() {
// 构造器中打印被实例化语句测试 时机:在第一次获取实例时 有且仅有一次
System.out.println("idCard2 被实例化了");
}
// 静态获取实例的方法
public static IdCard2 getIdCard() {
//判断如果idCard为空,则创建一个实例
if (idCard == null) {
idCard = new IdCard2();
return idCard;
}
// 已经存在实例,直接返回
return idCard;
}
}
线程安全问题解决
刚刚提到懒汉式存在线程安全问题,所以我们解决思路是,既然会有多个线程同时进入到if判断里创建对象,那么我们只需要在获取实例的方法上 加锁 让方法变成同步的 即可。 加入 synchronized 关键字
//懒汉式单例
public class IdCard2 {
private static IdCard2 idCard;
//构造器私有化
private IdCard2() {
// 构造器中打印被实例化语句测试 时机:在第一次获取实例时 有且仅有一次
System.out.println("idCard2 被实例化了");
}
// 静态获取实例的方法 使用 synchronized 锁机制保证线程安全
public synchronized static IdCard2 getIdCard() {
//判断如果idCard为空,则创建一个实例 加锁保证线程安全
if (idCard == null) {
idCard = new IdCard2();
return idCard;
}
// 已经存在实例,直接返回
return idCard;
}
}
标签:java,idCard,IdCard2,实例,线程,单例,设计模式,public
From: https://blog.csdn.net/m0_75269526/article/details/136751965