单例设计模式
- 单例模式应用实例
- 饿汉式
- 懒汉式
- 饿汉式 vs 懒汉式
单例模式应用实例
演示饿汉式和懒汉式单例模式的实现。
步骤如下:
1) 构造器私有化 ;(防止直接 new)
2) 类的内部创建对象;
3) 向外暴露一个静态的公共方法;
4) 代码实现。
饿汉式
没有使用这个实例但是已经创建了对象。
public class SingleTon01 {
public static void main(String[] args) {
// 通过方法可以获取对象
GirlFriend xb = GirlFriend.getInstance();
System.out.println(xb);
}
}
// 有一个类, GirlFriend
// 只能有一个女朋友
class GirlFriend {
private String name;
// 为了能给个在静态方法中, 返回 gf 对象,需要将其修饰为 static
// 对象,通常是重量级的对象,饿汉式可能造成创建了对象,但是没有使用
private static GirlFriend gf = new GirlFriend("小白");
// 如何保障我们只能创建一个 GirlFriend 对象
// 步骤[单例模式 —— 饿汉式]:
// 1. 将构造器私有化
// 2. 在类的内部直接创建对象(该对象是 static)
// 3. 提供一个公共的 static 方法,返回 gf 对象
private GirlFriend(String name) {
this.name = name;
}
public static GirlFriend getInstance(){
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
运行结果:
懒汉式
不去使用就不会创建对象。
public class SingleTon02 {
public static void main(String[] args) {
Cat cat = Cat.getInstance();
System.out.println(cat);
Cat cat1 = Cat.getInstance();
System.out.println(cat1);
System.out.println(cat == cat1);
}
}
class Cat{
private String name;
private static Cat cat;
// 希望在程序运行过程中,只能创建一个 Cat 对象
// 步骤[单例模式 —— 懒汉式]:
// 1. 构造器私有化
// 2. 定义一个 static 静态属性
// 3. 提供一个公共的 static 方法,返回 Cat 对象
// 4. 懒汉式,只有当用户使用 getInstance 时,才会返回 cat 对象
// 后面再次调用时,会返回上次创建的对象,从而保证单例
private Cat(String name) {
System.out.println("构造器被调用...");
this.name = name;
}
public static Cat getInstance(){
if (cat == null){ // 如果还没有创建 Cat 对象
cat = new Cat("Katie");
}
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
运行结果:
饿汉式 vs 懒汉式
1) 二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建;
2) 饿汉式不存在线程安全问题,懒汉式存在线程安全问题;
3) 饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。
4) 在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式。