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的其他函数
.....
//
}
有些对象我们只需要一个。单件模式没有全局变量的缺点:全局变量需要在一开始就创建,万一这个全局变量很耗资源,而又一直没有用到它,就很浪费,单件模式可以在需要的时候再创建。
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的其他函数
.....
//
}
相关文章推荐
- 【设计模式学习笔记】Singleton单件模式
- 设计模式系列一创建型之(单件模式)
- 【剑指offer】题2:实现单件(singleton)模式
- 从实例重温工厂模式和单件模式
- 自己理解的单件模式
- .Net Framework中使用的模式-Singleton模式
- 单件模式
- 设计模式学习笔记(8):单件模式
- [转帖]ASP.NET MVC Framework与WCSF中MVP模式之小小比较
- singleton pattern--单件模式
- Head First Design patterns笔记-Singleton patterns (从“一夫一妻制社会中婚约的达成”看单件模式)
- 单件模式(Singleton Pattern)
- 静态类、单件模式的区别
- 单件模式
- .NET设计模式(2):单件模式(Singleton Pattern)
- 2. Singleton单件(创建型模式)
- 设计模式学习--单件模式
- [导入]C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式).zip(9.57 MB)
- 我的心里只有你--单件模式(√4)
- 设计模式之单件模式