案例介绍
为什么需要单例模式?
比如,一个游戏只能有一个音乐播放器(如果有两个就会声音打架),或者一台电脑只能有一个鼠标光标,这时候就用单例模式保护它!
案例代码
1.饿汉式(最简单,线程安全)
public class CandyJar {
// 1. 直接创建一个唯一的糖果罐(类加载时就创建)
private static final CandyJar instance = new CandyJar();
// 2. 禁止外部 new 对象(保护魔法规则)
private CandyJar() {}
// 3. 提供获取唯一实例的方法
public static CandyJar getInstance() {
return instance;
}
}
特点:简单、线程安全,但可能浪费资源(如果一直不用这个实例)。
2.懒汉式(延迟创建,线程不安全)
public class CandyJar {
private static CandyJar instance; // 先不创建
private CandyJar() {}
// 第一次调用时创建实例(延迟加载)
public static CandyJar getInstance() {
if (instance == null) {
instance = new CandyJar(); // 线程不安全!
}
return instance;
}
}
问题:多线程下可能创建多个实例!
3.懒汉式 + 同步锁(线程安全但效率低)
public class CandyJar {
private static CandyJar instance;
private CandyJar() {}
// 加锁保证线程安全,但每次调用都要锁,效率低
public static synchronized CandyJar getInstance() {
if (instance == null) {
instance = new CandyJar();
}
return instance;
}
}
缺点:性能差(锁的代价太高)。
4.双重检查锁(最优解,线程安全+高效)
public class CandyJar {
// 用 volatile 禁止指令重排序
private static volatile CandyJar