设计模式之单例模式

该对象只有一个实例存在。也降低了内存的一个使用频率省去内存开销。
(题外话:单例上如果用到外表的context,即使用Application下的context,防止内存泄露)
public class Singleton{
//持有私有方法静态实例,防止被引用,此处赋值为null,目的是为了实现延迟加载
private static Singleton instance = null ;
//构造方法私有化,防止被实例化
private Singleton(){
}
//提供静态公共方法,创建实例
public static Singleton getInstance(){
          if(instance==null){
          instance = new Singleton();
          }
          return instance;
          }
}
这个基本满足需求,但是像这样毫无线程安全保护的类,如果把它放在多线程的环境下,肯定就会出问题了。
对getInstance 方法加 synchronized关键字,如下:
  public static synchronized Singleton getInstance(){
       if(instance ==null){
       instance = new Singleton();
       }
       return instance;
       }

但是synchronized 关键字锁住的是对象,这样用,在性能上会有所下降,每次调用这个方法,都会对对象上部锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。我们改成下面这个:
----------

    public static Singleton getInstance() {  
            if (instance == null) {  
                synchronized (instance) {  
                    if (instance == null) {  
                        instance = new Singleton();  
                    }  
                }  
            }  
            return instance;  
        }  

似乎解决了之前提到的问题,将synchronized关键字加在了内部,也就是说当调用的时候是不需要加锁的,只有在instance为null,并创建对象的时候才需要加锁,性能有一定的提升。但是,这样的情况,还是有可能有问题的,看下面的情况:在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。这样就可能出错了

对该程序做进一步优化:
  实际情况是,单例模式使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。这样我们暂时总结一个完美的单例模式:
    public class Singleton {  

        /* 私有构造方法,防止被实例化 */  
        private Singleton() {  
        }  

        /* 此处使用一个内部类来维护单例 */  
        private static class SingletonFactory {  
            private static Singleton instance = new Singleton();  
        }  

        /* 获取实例 */  
        public static Singleton getInstance() {  
            return SingletonFactory.instance;  
        }  

        /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
        public Object readResolve() {  
            return getInstance();  
        }  
    }  

还有人这么写:
 public class Singleton {  

    private static Singleton instance = null;  

    private Singleton() {  
    }  

    private static synchronized void syncInit() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
    }  

    public static Singleton getInstance() {  
        if (instance == null) {  
            syncInit();  
        }  
        return instance;  
    }  
}

借鉴:http://blog.csdn.net/shineflowers/article/details/19159879
确实不错,喜欢的请点赞哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值