美文网首页
设计模式之单例模式

设计模式之单例模式

作者: 小婷android | 来源:发表于2017-12-04 15:53 被阅读0次

    在我们的开发中,很多时候为了避免多次创建同一个对象,而选择使用了单例模式,这样让我们节省了内存的消耗,对于开发是大有好处的。
    最开始的时候,我写单例模式是这样的,代码如下:

    public class Single {
        private static Single mSingle = null;
    
        public Single() {
        }
    
        public static Single getSingle() {
            if (mSingle == null) {
                mSingle = new Single();
            }
            return mSingle;
        }
    }
    

    这样的写法,针对单个线程是没有问题的,由于mSingle是静态的,所以可以保证每次运行的的时候只存在一个实例;但是对于多线程的开发就存在问题了,比如我有两个线程A、B,同时去访问getSingle()方法,这个时候会各自new出一个对象出来,这样就存在了两个实例,违背了单例模式的规则。然后我们可以将代码改进如下:

    public class Single {
        private static Single mSingle = null;
    
        public Single() {
        }
    
        public static Single getSingle() {
            synchronized (Single.class) {
                if (mSingle == null) {
                    mSingle = new Single();
                }
            }
            return mSingle;
        }
    
    }
    

    针对上述问题,我加了一个所机制,让他有序的去访问getSingle()方法,如果只是两三个线程的话,这样写是没有多大问题的,但是我们想一想,如果,在一个开发中有几百或者几千个线程呢?这样的话就存在一定的问题了,比如,首先是100个线程同时去抢mSingle的所有权,当一个线程抢到了,然后剩下的99个在继续这样抢,依此往下推,可能存在一个运气不好的,知道最后才抢到mSingle的所有权,那么客户端那边等待它返回的数据的时候就会过长,这对于开发者来说是不行的。
    我们需要看一下上述代码,真的需要每次进入getInstance方法都要获得锁吗?其实不是的,整个Singleton类中,对mSingle进行访问的地方分为两类:读和写,而且仅当mSingle为null的时候才会写,mSingle一旦创建完毕,后面就只剩下读操作了,再怎么高并发也没什么关系了,反正mSingle已经是现成的,直接读就可以了。
    所以,我们又可以对代码做如下修改:

    public class Single {
        private static Single mSingle = null;
    
        public Single() {
        }
    
        public static Single getSingle() {
            if (mSingle == null) {
                synchronized (Single.class) {
                    if (mSingle == null) {
                        mSingle = new Single();
                    }
                }
            }
            return mSingle;
        }
    
    }
    

    最终,写下一种完全应用高并发的单例模式

    public class Single {
    
        private Single() {
        }
    
        private static class InstanceHolder {
            private static final Single instance = new Single();
        }
    
        public static Single getInstance() {
            return InstanceHolder.instance;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:设计模式之单例模式

          本文链接:https://www.haomeiwen.com/subject/otjxixtx.html