#21种设计模式之--3--Singleton(单例模式)#

作用:  

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

好处:

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

 单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。 
   
单例模式可以再系统设置全局的访问点,优化和共享资源访问。

使用情况:

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

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

使用方法

第一种形式:

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

1.2android中的Singleton

软键盘管理的 InputMethodManager

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

public final class InputMethodManager {
//.........
static InputMethodManager sInstance;
//.........
public static InputMethodManager getInstance() {
synchronized (InputMethodManager.class) {
if (sInstance == null) {
    IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
    IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
    sInstance = new InputMethodManager(service, Looper.getMainLooper());
}
    return sInstance;
}
}

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

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

public static synchronized CalendarDatabaseHelper getInstance(Context context) {
if (sSingleton == null) {
    sSingleton = new CalendarDatabaseHelper(context);
}
    return sSingleton;
}

注意Application并不算是单例模式

public class Application extends ContextWrapper implements ComponentCallbacks2 {

public Application() {
    super(null);
}

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

在ContextWrapper源码中:

public class ContextWrapper extends Context {
Context mBase;
 
public ContextWrapper(Context base) {
    mBase = base;
}

protected void attachBaseContext(Context base) {
if (mBase != null) {
    throw new IllegalStateException("Base context already set");
}
    mBase = base;
}

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

然并卵

猜你喜欢

转载自blog.csdn.net/duanpengde123/article/details/89814057