1.饿汉式
类加载的时候就会初始化,他是线程安全的,但是类加载的时候就初始化这样会预先消耗一部分资源。
/**
* Created by lijiayi on 2017/3/1.
* 饿汉式单例
*/
public class Singleton {
//生成单例对象
private static final Singleton mSingleton = new Singleton();
//私有化构造方法
private Singleton() {
}
//获取单例对象
public static Singleton getInstance() {
return mSingleton;
}
}
2.懒汉式
当第一次使用的时候才创建对象,合理占用资源,但是当该对象已经创建的时候,调用getInstance()方法会产生不必要的开销,这是懒汉式的一个缺点。
/**
* Created by lijiayi on 2017/3/1.
* 懒汉式单例
*/
public class Singleton {
//声明单例对象
private static Singleton mSingleton;
//私有化构造方法
private Singleton() {
}
//同步该方法获取单例对象
public static synchronized Singleton getInstance() {
//当该对象为空的时候创建该对象
if (mSingleton == null) {
mSingleton = new Singleton();
}
//返回该对象实例
return mSingleton;
}
}
3.DCL式
该方式能保证在需要的时候才初始化单例,又能够保证线程安全,而且单例初始化后调用getInstance()不会进行同步锁。
/**
* Created by lijiayi on 2017/3/1.
* DCL单例
*/
public class Singleton {
//声明单例对象
private static Singleton mSingleton;
//私有化构造方法
private Singleton() {
}
//同步该方法获取单例对象
public static synchronized Singleton getInstance() {
//当该对象为空的时候先同步这个对象
if (mSingleton == null) {
synchronized (Singleton.class) {
//再判断是否为空
if (mSingleton == null) {
//如果还空的话 就创建对象
mSingleton = new Singleton();
}
}
}
//返回该对象实例
return mSingleton;
}
}
4.静态内部类式
该方式保证了资源预先消耗、不必要的同步、线程的安全问题,还避免了DCL模式在某些情况下失效的问题。所以笔者建议使用该单例模式。
/**
* Created by lijiayi on 2017/3/1.
* 静态内部类单例
*/
public class Singleton {
//私有化构造方法
private Singleton() {
}
//获取单例对象
public static Singleton getInstance() {
//返回内部类中的singleton对象
return SingletonHolder.singleton;
}
/**
* 静态内部类
* 第一次加载类的时候不用调用该类,创建singleton对象,
* 只有调用getInstance()方法时才会创建该对象。
*/
private static class SingletonHolder {
private static final Singleton singleton = new Singleton();
}
}
5.枚举式
枚举是线程安全的,而且任何情况下都是一个实例,他不能被序列化,也不能被反射,所以枚举单例也是一个不错的选择。
/**
* Created by lijiayi on 2017/3/1.
* 枚举式单例
* 枚举单例时线程安全的,在任何情况下都是一个单例
*/
public enum SingletonEnum {
//枚举的类型
INSTANCE;
// 单例中的函数
public void todoSomethings() {
System.out.println("do somethings");
}
}
//枚举单例的使用
SingletonEnum.INSTANCE.todoSomethings();```
***
###6.容器实现单例
它的好处是可以统一的管理单例,安卓中getSystemService(String name)就是用这种方式实现的。
``` java
/**
* Created by lijiayi on 2017/3/1.
* 容器模式单例
* 实现了程序中单例的统一管理
*/
public class SingletonManager {
private static Map<String, Object> singletonManagerMap = new HashMap<String, Object>();
//私有化构造方法
private SingletonManager() {
}
//注入程序中的单例
public static void registerSingleton(String key, Object instance) {
if (!singletonManagerMap.containsKey(key)) {
singletonManagerMap.put(key, instance);
}
}
//获取对于key值的单例对象
public static Object getInstance(String key) {
return singletonManagerMap.get(key);
}
}