定义:确保一个类只有一个实例,并自行实例化向整个提供这个实例。
单例类的3个要素:
1、一个私有的构造方法(保证外界无法实例化该对象)
2、一个私有的静态实例变量
3、一个公有的获取实例变量的方法
两中模式:
1、饿汉模式
在类装载(编译的时候)的时候实例化。
public class Singleton{
private Singleton(){}
private static Singleton mInstance = new Singleton();
public Singleton getInstance(){
return mInstance;
}
}
饿汉式存在的问题:
如果构造方法中存在过多的处理,会导致加载这个类时比较慢,可能引起性能问题。
如果使用饿汉式的话,只进行了类的装载,并没有实质的调用,会造成资源的浪费。
2、懒汉模式
public classs Singleton{
private static Singleton mInstance;
private Singleton(){}
public Singleton getInstance(){
if( null == mInstance){
mInstance = new Singleton();
}
return mInstance;
}
}
上述的代码在多个线程密集调用getInstance时,存在创建多个实例的可能。比如线程A进入null == sInstance这段代码块,而在A线程未创建完成实例时,如果线程B也进入了该代码块,必然会造成两个实例的产生。
懒汉模式优化
public classs Singleton{
private static Singleton mInstance;
private Singleton(){}
public Singleton synchronized getInstance(){
if( null == mInstance){
mInstance = new Singleton();
}
return mInstance;
}
}
使用synchrnozed修饰getInstance方法可能是最简单的一个保证多线程保证单例唯一性的方法。
synchronized修饰的方法后,当某个线程进入调用这个方法,该线程只有当其他线程离开当前方法后才会进入该方法。所以可以保证getInstance在任何时候只有一个线程进入。
关于保证多线程下单例唯一的还有两种方法如下,可以在参考原文中找到,因为还不是特别理解,所以先不写在一起。
1、双重加锁
2、static机制
存在的疑问
1、真的只有一个实例吗
2、能否被继承
3、和静态变量的区别
4、关于GC
应用
1、数据库连接类
参考原文:http://droidyue.com/blog/2015/01/11/looking-into-singleton/