在面试中,遇到手写一个单例,平时敲代码没问题,但是手写。。。。乱七八糟,所以回来以后整理下单例
文章学习于 https://blog.csdn.net/anyanyan07/article/details/72039601
单例流程:
1.私有构造方法
2.创建单例对象
3.为外界提供获取单例对象的方法
随着不断的优化,单例模式也越加丰富多彩。下面是我为联系手感而附上的代码
/** * Created by ** * 饿汉式 * 优点:简单,线程安全 * 缺点:实例对象是static 在声明的时候就会实例化,浪费资源 */ public class SingleTon1 { /** * 1.私有构造方法 */ private SingleTon1() { } //创建实例对象 private static final SingleTon1 singleTonInstance = new SingleTon1(); /** * 对外提供方法,返回实例对象 * @return */ public static SingleTon1 getInatance() { return singleTonInstance; } }
/** * Created by ** * 优点:用到的时候才去实例化,在一定程度上节约了资源 * 缺点:getInstance方法是用synchronized修饰的,该方法是同步的,为了保证线程安全,但是导致每次调用该方法的时候都会被同步,这样会消耗不必要的资源(不必要的同步开销)。所以这种模式一般不建议使用 */ public class SingleTon2 { //私有构造方法 private SingleTon2() { } private static SingleTon2 singleTonInstatce; //懒汉式 private static synchronized SingleTon2 getInstance() { if (null == singleTonInstatce) { singleTonInstatce = new SingleTon2(); } return singleTonInstatce; } }
/** * Created by ** * 优点:第一次执行getInstance方法时才会实例化,资源利用率高,效率高。 * 缺点:偶尔失效(高并发条件下,由于JDK版本问题,在jdk1.5之前会失败) */ public class SingleTon3 { //私有化声明 private static SingleTon3 singleInstance; //私有构造函数 private SingleTon3() { } /** * 双重锁定 * getInstance()方法对singleTonInstance进行两次判空,对懒汉式进行了优化,只有在第一次实例化的时候才会走第二个分支,才会同步,避免了每次都同步造成的不必要的资源消耗。 */ public static SingleTon3 getInstance() { if (singleInstance == null) { synchronized (SingleTon3.class) { if (singleInstance == null) { singleInstance = new SingleTon3(); } } } return singleInstance; } }
/** * Created by ** * 优点:线程安全,保证单例的唯一性,延迟了对象的实例化,是推荐的方式 */ public class SingleTon4 { //私有化构造方法 private SingleTon4() { } public static SingleTon4 getInstance() { return SingleTonHolder.singleInstance; } //第一次调用getInstance()方法的时候,虚拟机才会加载SingleTonHoulder静态内部类 public static class SingleTonHolder { private static final SingleTon4 singleInstance = new SingleTon4(); } }注意,在如果需要持有Context时,介意使用Application的context(生命周期长),不会造成没必要的内存泄露。