设计模式——单例模式

单例模式是我们比较常用的设计模式之一。一般有这几种比较常用的写法:

1、饿汉模式

public class HungrySingleton {

    private static HungrySingleton mInstance = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getInstance(){
        return mInstance;
    }
}

这种模式基于classloader机制,避免了多线程同步的问题,但是由于在类加载就实例化可能会造成内存的浪费。我们比较喜欢用到的时候再实例化,也就是我们常说的lazy loading效果。

2、懒汉模式

public class LazySingleton {
    
    private static LazySingleton mInstance;
    
    private LazySingleton(){}
    
    public static LazySingleton getInstance(){
        if (mInstance==null){
            mInstance = new LazySingleton();
        }
        return mInstance;
    }
}

懒汉模式很明显使用的是lazy loading。但是它有一个致命的弱点就是没办法在多线程中正常工作。改进方式是给getInstance()添加synchronized关键字,这样一来既保留了lazy loading,也能够在多线程中工作。但是会导致新的问题:效率过低,因为大多数情况都不需要同步。

3、静态内部类模式

public class InnerSingleton {
    
    private InnerSingleton (){}
    
    public static InnerSingleton getInstance(){
        return Inner.INSTANCE;
    }
    
    private static class Inner{
        private static final InnerSingleton INSTANCE = new InnerSingleton();
    }
}

这种模式的单例,可以正常的在多线程中工作,同时也达到了lazy loading效果。推荐使用

4、双重校验加锁单例

public class DoubleCheckSingleton {

    private static volatile DoubleCheckSingleton mInstance;

    private DoubleCheckSingleton (){}

    public static DoubleCheckSingleton getInstance(){
        if (mInstance==null){
            synchronized (DoubleCheckSingleton.class){
                if (mInstance==null){
                    mInstance = new DoubleCheckSingleton();
                }
            }
        }
        return mInstance;
    }
}

首先很明显能够看到getInstance()方法中有两次判空操作,volatilesynchronized关键字能够有效的保证了再多线程中的正确运行。但是由于volatile关键字是在jdk1.5才有的。这种方式在1.5之前可能会导致多线程运行异常。也就是常说的DCL失效。

5、枚举单例

public enum  EnumSingleton {
    INSTANCE;

    public void doSomething(){
        // TODO
        System.out.println("我是枚举单例");
    }
}

写法简单是枚举单例的优点。因为枚举和普通的java类一样,可以拥有变量和方法。并且默认枚举是多线程安全,因此这也是一种比较推荐的写法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值