前言
为了避免重复创建对象,我们需要学习使用单例模式。推荐使用饿汉模式。
实现
- 懒汉模式
- 饿汉模式
- 双检锁/双重校验锁
- *
懒汉模式
最简单的一种实现,实现懒加载,但是不适用于多线程。
懒加载:需要时才加载,不加载不占用空间。
实现代码
public class LazzySingleInstance {
public static LazzySingleInstance instance;
private LazzySingleInstance(){
}
public static LazzySingleInstance getInstance(){
if (instance==null){
instance=new LazzySingleInstance();
}
return instance;
}
}
饿汉模式
利用Java的 ClassLoader 机制,在类加载期间进行对象初始化,能在多线程下执行(线程安全)。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
只是在懒汉模式下改动了几行代码。
实现代码
public class HungrySingleInstance {
public static HungrySingleInstance instance=new HungrySingleInstance();
private HungrySingleInstance(){
}
public static HungrySingleInstance getInstance(){
return instance;
}
}
验证
让我们 Fucking 测试一下,测试代码如下
LazzySingleInstance lazzySingleInstance1=LazzySingleInstance.getInstance();
LazzySingleInstance lazzySingleInstance2=LazzySingleInstance.getInstance();
System.out.println("懒汉模式:是否指向同一对象"+lazzySingleInstance1.equals(lazzySingleInstance2));
HungrySingleInstance hungrySingleInstance1=HungrySingleInstance.getInstance();
HungrySingleInstance hungrySingleInstance2=HungrySingleInstance.getInstance();
System.out.println("饿汉模式:是否指向同一对象"+hungrySingleInstance1.equals(hungrySingleInstance2));
双检锁/双重校验锁(DCL,即 double-checked locking)
双重锁:两次判断,一次加锁。
这种方式采用双锁机制,但是加锁影响性能。
public class DclSingleInstance {
private DclSingleInstance (){
}
// volatile 关键字改良双重检验机制
public volatile static DclSingleInstance instance;
public static DclSingleInstance getInstance() {
if (instance==null){
synchronized (DclSingleInstance.class){
if (instance==null){
instance = new DclSingleInstance();
}
}
}
return instance;
}
}