单例模式的几种实现

1.饿汉模式 – 线程安全,调用效率高
在类被加载时初始化instance,调用私有的构造函数,创建单例类的唯一实例。(不能延时加载)
(构造函数是私有的,因此该类不能被继承)

/*
 * 饿汉模式  
 */
public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    //私有的构造函数
    private EagerSingleton(){}
    //getInstance()方法
    public static EagerSingleton getInstance(){
        return instance;
    }
}

2.懒汉模式
类的构造函数是私有的,与饿汉模式不同,instance是在第一次被引用时进行实例化。(延时加载)
懒汉式有两种实现方式:线程安全和线程不安全的
a)第一种写法,在第一次被引用时进行实例化

/*
 * 第一种写法,线程不安全
 */
public class LazySingleton1 {
    private static LazySingleton1 instance = null;
    //私有的构造函数
    private LazySingleton1(){}
    public static LazySingleton1 getInstance(){
        if(instance==null){
            instance = new LazySingleton1();//有可能有多个线程进入此状态,导致创建了多个实例。
        }
        return instance;
    }
}

b)第二种写法
加入同步锁(synchronized)

/*
 * 第二种写法,线程安全
 */
public class LazySingleton2 {
    private static LazySingleton2 instance = null;
    //私有的构造函数
    private LazySingleton2(){}
    /*加入同步锁,迫使每个线程在进入该方法前。要等候别的线程离开该方法,即不会有两个线程同时调用该方法
    *缺点:只有第一次执行此方法时才需要同步,如果每次调用都同步,降低性能
    */
    public static synchronized LazySingleton2 getInstance(){
        if(instance==null){
            instance = new LazySingleton2();
        }
        return instance;
    }
}

3.双重检查加锁 –线程安全
首先检查实例是否已经创建了,未创建才进行同步

public class DoubleCheckLocking {
    //volatile关键字确保实例化时多个线程能正确处理instance变量
    private volatile static DoubleCheckLocking instance = null;
    //私有构造函数
    private DoubleCheckLocking(){}
    public static DoubleCheckLocking getInstance() {
        if(instance == null){//检查该实例是否存在,不存在则进入同步区块
            synchronized (DoubleCheckLocking.class) {
                if(instance==null){//进入同步区块后再检查一次,如果仍然不存在才创建实例
                    instance = new DoubleCheckLocking();
                }
            }
        }
        return instance;        
    }
}

4.静态内部类模式–线程安全,调用效率高
调用getInstance()方法时,才实例化instance

public class InnerclassSingleton {
    //静态内部类
    private static class InnerclassSingletonGetInstance {
        public static final InnerclassSingleton instance = new InnerclassSingleton();
    }
    //私有构造器
    private InnerclassSingleton() {
    }
    //只有调用getInstance()时,才会加载类InnerclassSingletonGetInstance,并实例化instance
    public static  InnerclassSingleton getInstance() {
        return InnerclassSingletonGetInstance.instance;
    }
}

5.枚举模式 – 线程安全 调用效率高

enum EnumSingleton {
    INSTANCE;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值