Chinaunix首页 | 论坛 | 博客
  • 博客访问: 291458
  • 博文数量: 68
  • 博客积分: 1474
  • 博客等级: 上尉
  • 技术积分: 616
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-12 12:07
文章分类

全部博文(68)

文章存档

2011年(68)

分类: 嵌入式

2011-07-19 10:30:53

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


  1. public class BluetoothOppManager {

  2.     private static BluetoothOppManager INSTANCE;

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

  5. /**
  6.     * Get singleton instance.
  7.     */
  8.    public static BluetoothOppManager getInstance(Context context) {
  9.        synchronized (INSTANCE_LOCK) {
  10.            if (INSTANCE == null) {
  11.                INSTANCE = new BluetoothOppManager();
  12.            }
  13.            INSTANCE.init(context);

  14.            return INSTANCE;
  15.        }
  16.    }

  17. }

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

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


  1. public static BluetoothOppManager getInstance(Context context) {

  2.        if(INSTANCE == null)
  3.            synchronized (INSTANCE_LOCK) {
  4.                if (INSTANCE == null) {
  5.                    INSTANCE = new BluetoothOppManager();
  6.                }
  7.                INSTANCE.init(context);

  8.           }

  9.            return INSTANCE;
  10.        }
  11.    }

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

阅读(1738) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

tianbianfei2011-07-20 22:54:31

太好了,楼主,真牛人!楼主知道anroid签名是怎么回事吗?可以到http://www.doumiw.com/market/community/t!showTopic.do?topicId=24帮忙回答吗,谢谢!