单例模式总结

饿汉式单例:

优点:线程安全,使用时没有延迟

缺点:启动时就创建了实例,启动慢,可能造成资源浪费

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, SingleTonParent> INSTANCES_MAP = new HashMap<>();

    public synchronized static  SingleTonParent getInstance(Class 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);

你可能感兴趣的:(单例模式总结)