Framework中的单件模式

首先了解下单件模式

有些对象我们只需要一个。单件模式没有全局变量的缺点:全局变量需要在一开始就创建,万一这个全局变量很耗资源,而又一直没有用到它,就很浪费,单件模式可以在需要的时候再创建。

package com.amaker.app;

 

public class Singleton {

//利用一个静态变量来记录Singleton类的唯一实例

private static Singleton uniqueInstance;

//把构造函数声明为私有的,只有Singleton类内才可以调用构造器

private Singleton(){}

//在代码的任何地方调用静态方法getInstance方法实例化对象,并返回这个实例

public static Singleton getInstance(){

if(uniqueInstance == null)

{

uniqueInstance new Singleton();

}

return uniqueInstance;

}

}

 

下面我们用单例模式来设计一个巧克力炉,如下:

package com.amaker.app;

public class Chocolateboiler {
 
    privateboolean empty;
      privateboolean boiled;
      privatestatic Chocolateboiler uniqueInstance;
      privateChocolateboiler(){
            empty =true;
            boiled =false;
      }
      publicstatic synchronized Chocolateboiler getInstance(){
            if(uniqueInstance != null)
            {
                  uniqueInstance = new Chocolateboiler();
            }
            returnuniqueInstance;
      }
      public voidfill(){
            if(isEmpty())
            {
                  empty =false;
                  boiled =false;
            }
      }
      public voiddrain(){
            if(!isEmpty() && !isBoiled())
            {
                  empty =true;
            }
      }
      public voidboil(){
            if(!isEmpty() && !isBoiled()){
                  boiled =true;
            }
      }
      publicboolean isEmpty(){
            returnempty;
      }
      publicboolean isBoiled(){
            returnempty;
      }
}
但这样的简单单件设计会在多线程的时候遇到问题,所以这里我们为这个函数加上了同步(不过同步一个方法可能使程序执行效率下降100倍?所以在不是频繁使用此方法的时候还行)。
上面的做法是延迟实例化,这里我们用“急切”创建单件实例。
2.事先创建单件实例
      //在静态初始化器中创建单件,保证了线程安全
      privatestatic Chocolateboiler uniqueInstance = newChocolateboiler();
      //有实例之后直接使用就是
      publicstatic Chocolateboiler getInstance(){
            returnuniqueInstance;
      }
3.还有一种方法是用"双重检查加锁",在getInstance()中减少使用同步。
private volatile static Chocolateboiler uniqueInstance;
      publicstatic Chocolateboiler getInstance(){
            if(uniqueInstance == null)
            {//检查实例,如果不存在就进入同步块,这样只有第一次才彻底执行这里的代码。
                  synchronized(Chocolateboiler.class){
                        if(uniqueInstance == null){//进入同步块之后,再检查一次,如果仍是null,才创建实例
                              uniqueInstance = new Chocolateboiler();
                        }
                  }
            }
            returnuniqueInstance;
      }
//不过因为JVM的实现,java1.4及之前的版本不支持这个技巧

//-----------------------------------------------------------------------------------------------------------------------------------------------------------
Android 的Framework中(Android TV系统,这里工厂菜单的添加使用了这种模式,Android原生代码中没这个代码)
//jb4.3-mstar-master\device\mstar\common\libraries\tv\java\com\mstar\android\tv\TvFactoryManager.java
public class TvFactoryManager {
    private final static String TAG = "TvFactoryManager";

    //定义了一个静态变量mInstance
       static TvFactoryManager mInstance = null;
//定义了一个静态变量mService
    private static ITvFactory mService = null;
//构造函数声明为私有的
    private TvFactoryManager() {
    }

    public static TvFactoryManager getInstance() {
        /* Double-checked locking */
        if (mInstance == null) {
            synchronized (TvFactoryManager.class) {
                if (mInstance == null) {
                    mInstance = new TvFactoryManager();
                }
            }
        }

        return mInstance;
    }

    private static ITvFactory getService() {
        if (mService != null) {
            return mService;
        }

        mService = TvManager.getInstance().getTvFactory();
        return mService;
    }
}

这样在FactoryMenuManagerImpl中就可以获取并使用这个单例了。
public class FactoryMenuManagerImpl implements FactoryMenuManager {
    private static TvFactoryManager factormanager;

public FactoryMenuManagerImpl() {
        if(factormanager == null){
            factormanager = TvFactoryManager.getInstance();
        }
    }
//FactorymenuManagerImpl的其他函数
.....
//
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值