Singleton pattern

Singleton pattern

什么是单例模式 ?

       单例模式是软件开发中的一种设计模式,它的作用在于可以限制我们实例化对象的次数(即一个对象只能初始化一次),以此减少开辟内存空间,节省系统资源.

单例模式的书写

1.双重锁(DLC)

/**
 * If the code is not wrong its author is JokerCats.
 */

public class Singleton {

    // 因为newInstance方法中的判断依据为instance,所以应该保证
    // instance与newInstance同为static修饰(不要忘记给instance对象设置初始值)
    private static Singleton instance = null;

    // 因为是单例模式,为了限制我们创建Singleton对象的次数
    // 所以将创建方法的权限设置为私有(外部不可随意调用)
    private Singleton() {

    }

    // 向外部暴露一个静态方法用来实例化我们的Singleton对象
    // 但由于该对象还没有被创建出来,导致不能直接调用该类中的方法
    // 所以在该方法前加static进行修饰,用类名.方法的方式进行创建
    public static Singleton newInstance() {

        if (null == instance) {
            // 提高性能,如果对象不为空 表示该对象已经被创建了,所以直接使用已经创建的就好
            synchronized (Singleton.class) {
                // 因为线程是抢占式运行,所以通过加锁的方式让线程更为安全
                if (instance == null) {
                    // 在第一进来的时候判断对象是否为空,如果为空就进行创建
                    instance = new Singleton();
                }
            }
        }
        // 此处返回我们创建的对象
        return instance;
    }
}

2.懒汉式

public class Singleton {

    // 采用静态内部类的形式
    private static class LazyHolder{
        // 这种形式虽然该Singleton被装载了,但是INSTANCE对象却不一定被初始化
        // 只有调用了newInstance方法的时候才会进行实例化
        private static final Singleton INSTANCE = new Singleton();
    }

    // 将创建方法的权限设置为私有(外部不可随意调用)
    private Singleton(){

    }

    // 对外部暴露一个静态方法,并将该方法用static进行修饰,方便直接用类名进行调用
    public static Singleton newInstance(){
        return LazyHolder.INSTANCE;
    }
}

3.饿汉式

public class Singleton {

    // 该写法的思路是,不论你是否使用,都先初始化好
    private static final Singleton INSTANCE = new Singleton();

    // 将创建方法的权限设置为私有(外部不可随意调用)
    private Singleton() {

    }

    // 对外部暴露一个静态方法,并将该方法用static进行修饰,方便直接用类名进行调用
    public static Singleton newInstance() {
        // 然后调用该方法时,直接将已经初始化好的对象返回
        return INSTANCE;
    }
}  

4.枚举 (如果不明白什么是枚举的Cats可以点击链接)

public enum  Singleton {

    INSTANCE;
    public void newInstance(){
        // 该写法Effective Java作者Josh Bloch提倡的方式
        // 它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
    }
}  

5.原子引用

public class Singleton {

    // 创建原子引用的对象
    private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();

    public static Singleton getInstance() {
        // 死循环,直到指定的退出为止(个人认为该写法与Linux中的自旋锁写法有异曲同工之妙)
        for (; ; ) {
            // INSTANCE.get 是从AtomicReference的对象中查找元素(加入AtomicReference中的元素能保证原子性)
            // 如果能得到元素就说明已经创建了单例对象,如果没有就创建个单例对象并加入AtomicReference中
            Singleton current = INSTANCE.get();
            if (current != null) {
                return current;
            }

            current = new Singleton();
            // 先去AtomicReference中取值,如果取到的值与expect相等就将update以原子的方式设置进去
            // 如果设置成功会返回true
            if (INSTANCE.compareAndSet(null, current)) {
                return current;
            }
        }

    }

    // 将创建方法的权限设置为私有(外部不可随意调用)
    private Singleton() {

    }
 }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值