单例模式使用比较常见,用来保证一个类仅有一个实例,并提供一个访问它的全局访问点。在Android application包中有个Bluetooth相关的包就用到了单例模式,实例代码如下:

public class BluetoothOppManager {

private static BluetoothOppManager INSTANCE;

/** Used when obtaining a reference to the singleton instance. */
private static Object INSTANCE_LOCK = new Object();

/**
* Get singleton instance.
*/
public static BluetoothOppManager getInstance(Context context) {
synchronized (INSTANCE_LOCK) {
if (INSTANCE == null) {
INSTANCE = new BluetoothOppManager();
}
INSTANCE.init(context);

return INSTANCE;
}
}

}

这里考虑到了多线程互斥的问题,引入了一个静态只读的进程辅助对象。它使得最先进入的那个线程来创建这个实例,以后的线程进入时不会创建实例对象。

不知道细心的读者发现没,这个getInstance()操作,每次被调用时,都会加上同步锁,这样会影响性能,所以有些改进的办法,见下文:

public static BluetoothOppManager getInstance(Context context) {

if(INSTANCE == null)
synchronized (INSTANCE_LOCK) {
if (INSTANCE == null) {
INSTANCE = new BluetoothOppManager();
}
INSTANCE.init(context);

}

return INSTANCE;
}
}

这种做法只有在实例未被创建的时候才加锁,同时也能保证多线程的安全,所以该做法又叫Double-Check Locking(双重锁定)。这时又有同学要问,为什么我前面已经判断了INSTANCE是否为null,为什么同步代码里面又做了一次判断?这个也不难理解,当INSTANCE为null时,两个线程同时调用,这时它们都可以通过第一轮判断,都会立马加锁,但是最先进入临界区的线程先加锁,后进入的等待之。知道先进去的哥们创建好之后出来释放为止。此时,INSTANCE已经被创建,所以后进去的哥们被唤醒时,一看INSTANCE已经被创建了,那我就不创建了,所以也就避免了被创建两次的尴尬。

最后附上单例模式的结构图:

更多相关文章

  1. 分析(Android下的任务和Activity栈)
  2. Application Fundamentals--Processes and Threads(进程与线程)
  3. Android应用程序线程消息循环模型分析(5)
  4. android volley 调用webService
  5. Android(安卓)面试复习资料
  6. Android知识点总结(二十)Android中的ANR
  7. android之handler和asynctask
  8. EventBus3.0源码解析(二):post()与postSticky()
  9. Android(安卓)URl网络获取图片

随机推荐

  1. Android中的BatteryService及相关组件
  2. Android
  3. Android的API版本和名称对应关系
  4. android kitkat(4.4以上)各个版本的特性解
  5. 使用Android(安卓)Studio开发FFmpeg的正
  6. Android(安卓)WebSocket通信通过Service
  7. 根据文字的多少,自动适应变化的表格...
  8. android camera 源码分析
  9. Android(安卓)SDK Manager 下载问题
  10. Android(安卓)文件及文件夹操作