1.饿汉式
public class SingletonInstance {
//私有构造方法
private static SingletonInstance (){
}
//声明成员变量
private static SingletonInstance singletonInstance = new SingletonInstance();
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
return singletonInstance ;
}
}
2.懒汉式
public class SingletonInstance {
//私有构造方法
private SingletonInstance (){
}
//声明成员变量
private static SingletonInstance singletonInstance ;
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
if(singletonInstance == null){
singletonInstance = new SingletonInstance();
}
return singletonInstance ;
}
}
饿汉式 懒汉式是经典的单例写法,但是线程不安全,当然,为保证线程安全,可以对getSingletonInstance()函数加锁,如下:
public static synchronized SingletonInstance getSingletonInstance(){
return singletonInstance = new SingletonInstance();
}
但是这样每次获取单例都会判断锁,会很消耗资源,所以饿汉式和懒汉式不推荐使用,推荐使用以下方式
3.double check lock(dcl)
public class SingletonInstance {
//私有构造方法
private SingletonInstance (){
}
//声明成员变量
private static SingletonInstance singletonInstance ;
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
if(singletonInstance == null){
synchronized (SingletonInstance.class){
//两次判断是否为null
if(singletonInstance==null){
singletonInstance = new SingletonInstance();
}
}
}
return singletonInstance ;
}
}
DCl 资源利用率高,执行效率也高,缺点是第一次加载的时候会比较慢,而且在高并发的时候,有可能会导致单例不成功(概率很小),推荐使用这种方式
4.静态内部类
public class SingletonInstance {
//私有构造方法
private SingletonInstance (){
}
private static class Builder{
//声明成员变量
private static SingletonInstance singletonInstance = new SingletonInstance();
}
//对外提供接口获取该实例
public static SingletonInstance getSingletonInstance(){
return Builder.singletonInstance ;
}
}
这种方法,实例只会被创建一次,而且只有在被引用的时候创建,线程安全也能保证,所以推荐使用这种方式
5.以上四种方法,不管哪种方法,在反序列化的时候,都不能保证单例。但是使用枚举可以避免这个问题,枚举默认就是线程安全的
public enum Singleton { //enum枚举类
INSTANCE;
}
但是枚举在android中是不建议使用的,因为枚举比constants消耗更大的内存,
6.单例管理类创建单例
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String,Object>();//使用HashMap作为缓存容器
private Singleton() {
}
public static void registerService(String key, Objectinstance) {
if (!objMap.containsKey(key) ) {
objMap.put(key, instance) ;//第一次是存入Map
}
}
public static ObjectgetService(String key) {
return objMap.get(key) ;//返回与key相对应的对象
}
}
7.反序列化杜绝生成新的实例,需要加入以下这个函数
private Object readResolve() throws ObjectStreamException{
return INSTANCE;
}