饿汉式单例:
优点:线程安全,使用时没有延迟
缺点:启动时就创建了实例,启动慢,可能造成资源浪费
public class Singleton1{
private Singleton1(){}
private static Singleton1 mSingleton1 = new Singleton1();
public static Singleton1 getInstance(){
return mSingleton1;
}
public static void main(String args[]){
System.out.println("------");
Singleton1.getInstance();
}
}
懒汉式单例:
- 线程不安全:(使用与单线程环境)
优点:懒加载,启动快,资源占用小,使用时才实例化,无锁
缺点:非线程安全
public class Singleton1{
private Singleton1(){}
private static Singleton1 mSingleton1;
public Singleton1 getInstance(){
if(mSingleton1 == null){
mSingleton1 = new Singleton1();
}
return mSingleton1;
}
}
- 线程安全:(适用于多线程,但是效率不高)
优点:懒加载,启动快,资源占用小,使用时才实例化,有锁
缺点:synchronized为独占排他锁,并发性能差。
每次调用getInstance时候都需要进行同步,造成不必要的同步开销,
public class Singleton1{
private Singleton1(){}
private static Singleton1 mSingleton1;
public static synchronized Singleton1 getInstance(){
if(mSingleton1 == null){
mSingleton1 = new Singleton1();
}
return mSingleton1;
}
}
- 双重检查加锁(DCL)
缺点:首次加载反应稍慢,在某些情况下存在DCL失效
public class Singleton1{
private Singleton1(){}
//用到了volatile关键字
//防止JVM的指令重排,造成指令顺序有所变化,
//指令重排后可能代码还未初始化,但是被调用,造成空指针问题
//如果此时线程B抢占cpu资源,执行第一个if判断的记过是false
//从而会返回一个没有初始化完成的instance对象。
private volatile static Singleton1 mSingleton1;
public static synchronized Singleton1 getInstance(){
//第一次防止不必要的同步
if(mSingleton1 == null){
synchronized(Singleton1.class){
//第二次为null时才创建实例
if(mSingleton1 = null){
mSingleton1 = new Singleton1();
}
}
}
return mSingleton1;
}
}
静态内部类方式的单例:
静态内部类不会在Singleton1加载时一起加载,只有第一次调用getInstance方法是时候,才会初始化mSingleton1,通过虚拟机来控制静态内部类的加载,防止被多次加载
public class Singleton1{
private Singleton1(){}
private static class InnerHolder{
private static final Singleton1 mSingleton1 = new Singleton1();
}
public Singleton1 getInstance(){
return InnerHolder.mSingleton1;
}
}
枚举实现单例:
实现简单,线程安全,无法进行懒加载
public enum Singleton {
INSTANCE;
}
// 定义单例模式中需要完成的代码逻辑
public interface MySingleton {
void doSomething();
}
public enum Singleton implements MySingleton {
INSTANCE {
@Override
public void doSomething() {
System.out.println("complete singleton");
}
};
public static MySingleton getInstance() {
return Singleton.INSTANCE;
}
}
泛型实现单例:
import java.util.HashMap;
import java.util.Map;
public class SingleTonParent{
private static Map<Class<? extends SingleTonParent>, SingleTonParent> INSTANCES_MAP = new HashMap<>();
public synchronized static <E extends SingleTonParent> SingleTonParent getInstance(Class<E> instanceClass) throws Exception {
if(INSTANCES_MAP.containsKey(instanceClass)){
return INSTANCES_MAP.get(instanceClass);
} else {
E instance = instanceClass.newInstance();
INSTANCES_MAP.put(instanceClass, instance);
return instance;
}
}
protected SingleTonParent(){
}
}
//继承泛型父类
public class Test extends SingleTonParent{}
//调用方法
Test test = (Test)SingleTonParent.getInstance(Test.class);