您的位置:首页 > 其它

Framework中的单件模式

2014-04-25 16:10 274 查看
首先了解下单件模式

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

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的其他函数

.....

//

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: