android单例

单例介绍

可以通俗的理解为该类有且只有一个实例;内部实例化对象;外部调用的时候只能调用该实例。它的目的是保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例优缺点

优点:
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。
缺点:
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

单例应用

1、资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件等。
2、控制资源的情况下,方便资源之间的互相通信。如线程池等。

单例实现

饿汉式:
优点:线性安全;在类加载的时候就已经实例化了,调用快。
缺点:资源效率低;有可能永远都不会调用到getInstance()方法。
懒汉式:
优点:避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。
缺点:懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。

双重锁:
双重锁出现的原因是因为多个线程等待时,最先进去的线程已经实例化了,但是后面的线程并知道,如果不在锁里面再判断一次单例对象,就会创建多个对象,违背了单例模式的设计思想。

public class Analytics {
    private volatile static Analytics analytics;
    public Analytics (){}
    public static Analytics getInstence(){
        if (analytics!=null){
            return analytics;
        }
        synchronized (Analytics .class){
            if (analytics==null){
                analytics= new Analytics ();
            }
        }
        return analytics;
    }
}

多唠叨一下volatile关键字,主要是禁止重排序,初始化一个实例(SomeType st = new SomeType())在java字节码中会有4个步骤:1、申请内存空间;2、初始化默认值(区别于构造器方法的初始化);3、执行构造器方法;4、连接引用和实例。这4个步骤后两个有可能会重排序,1234 1243都有可能,造成未初始化完全的对象发布。volatile可以禁止指令重排序,从而避免这个问题。new Analytics ()是一个非原子操作,编译器可能会重排序,而线程B在线程A赋值完时判断instance就不为null了,此时B拿到的将是一个没有初始化完成的半成品。volatile就能解决这个问题。

静态内部类:(推荐)

public class Analytics {
	public Analytics(){}
	public static class SingletonHelp {
		private final static Analytics instance = new Analytics();
	}
	public static Analytics getInstance(){
		return SingletonHelp.instance ;
	}
}

优点 :资源利用率高,不执行getInstance()不被实例,可以执行该类其他静态方法
缺点 :第一次加载时反应不够快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值