一、设计模式之单例模式

来源:互联网 发布:淘宝布局管理无法看 编辑:程序博客网 时间:2024/05/21 11:09

#1. Singleton(单例模式)

作用:  

保证在Java应用程序中,一个类Class只有一个实例存在。

好处:

由于单例模式在内存中只有一个实例,减少了内存开销。

 单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。   

单例模式可以再系统设置全局的访问点,优化和共享资源访问。

使用情况:

建立目录 数据库连接的单线程操作

某个需要被频繁访问的实例对象 

##1.1 使用方法

第一种形式:

public class Singleton {    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */    private static Singleton instance = null;    /* 私有构造方法,防止被实例化 */    private Singleton() {    }    /* 懒汉式:第一次调用时初始Singleton,以后就不用再生成了    静态方法,创建实例 */    public static Singleton getInstance() {        if (instance == null) {            instance = new Singleton();        }        return instance;    }}

  但是这有一个问题,不同步啊!在对据库对象进行的频繁读写操作时,不同步问题就大了。

第二种形式

  既然不同步那就给getInstance方法加个锁呗!我们知道使用synchronized关键字可以同步方法和同步代码块,所以:  

 public static synchronized Singleton getInstance() {       if (instance == null) {           instance = new Singleton();       }       return instance;   } 

或是

public static Singleton getInstance() {       synchronized (Singleton.class) {           if (instance == null) {               instance = new Singleton();           }       }       return instance;   } 

获取Singleton实例:

Singleton.getInstance().方法()

##1.2android中的Singleton

软键盘管理的 InputMethodManager

源码(以下的源码都是5.1的):

205 public final class InputMethodManager {//.........211     static InputMethodManager sInstance;//.........619     public static InputMethodManager getInstance() {620         synchronized (InputMethodManager.class) {621             if (sInstance == null) {622                 IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);623                 IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);624                 sInstance = new InputMethodManager(service, Looper.getMainLooper());625             }626             return sInstance;627         }628     }

  使用的是第二种同步代码块的单例模式(可能涉及到多线程),类似的还有   AccessibilityManager(View获得点击、焦点、文字改变等事件的分发管理,对整个系统的调试、问题定位等)   BluetoothOppManager等。

当然也有同步方法的单例实现,比如:CalendarDatabaseHelper

307     public static synchronized CalendarDatabaseHelper getInstance(Context context) {308         if (sSingleton == null) {309             sSingleton = new CalendarDatabaseHelper(context);310         }311         return sSingleton;312     }

注意Application并不算是单例模式

44 public class Application extends ContextWrapper implements ComponentCallbacks2 {79     public Application() {80         super(null);81     }

在Application源码中,其构造方法是公有的,意味着可以生出多个Application实例,但为什么Application能实现一个app只存在一个实例呢?请看下面:

在ContextWrapper源码中:

50 public class ContextWrapper extends Context {51     Context mBase;52 53     public ContextWrapper(Context base) {54         mBase = base;55     }64     protected void attachBaseContext(Context base) {65         if (mBase != null) {66             throw new IllegalStateException("Base context already set");67         }68         mBase = base;69     }

ContextWrapper构造函数传入的base为null, 就算有多个Application实例,但是没有通过attach()绑定相关信息,没有上下文环境,三个字。

然并卵

原创粉丝点击