單例模式屬於最常用的設計模式,Java中有很多實現單例模式的方式,各有其優缺點
實現方式對比
單例實現方式 | 線程安全 | 延遲加載 | 性能 | 複雜度 |
---|---|---|---|---|
餓漢式 | 安全 | 不支持 | 好 | 簡單 |
懶漢式 | 安全 | 支持 | 差 | 一般 |
雙重檢測 | 安全 | 支持 | 好 | 複雜 |
靜態內部類 | 安全 | 支持 | 好 | 簡單 |
枚舉 | 安全 | 不支持 | 好 | 最簡單 |
實現方式示例
實現一個ID生成器的單例
- 餓漢式: 不支持延遲加載
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static final IdGenerator instance = new IdGenerator();
private IdGenerator() {}
public static IdGenerator getInstance() {
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
- 懶漢式:延遲加載、性能差
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static synchronized IdGenerator getInstance() {
if (instance == null) {
instance = new IdGenerator();
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
- 雙重檢測:延遲加載、性能好
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static IdGenerator getInstance() {
if (instance == null) {
synchronized(IdGenerator.class) { // 此處爲類級別的鎖
if (instance == null) {
instance = new IdGenerator();
}
}
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
- 靜態內部類:延遲加載、性能好(推薦)
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private IdGenerator() {}
private static class SingletonHolder{
private static final IdGenerator instance = new IdGenerator();
}
public static IdGenerator getInstance() {
return SingletonHolder.instance;
}
public long getId() {
return id.incrementAndGet();
}
}
- 枚舉:實現最簡單
public enum IdGenerator {
INSTANCE;
private AtomicLong id = new AtomicLong(0);
public long getId() {
return id.incrementAndGet();
}
}