Chinaunix首页 | 论坛 | 博客
  • 博客访问: 460633
  • 博文数量: 101
  • 博客积分: 578
  • 博客等级: 中士
  • 技术积分: 872
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-12 22:24
文章分类

全部博文(101)

文章存档

2015年(1)

2014年(83)

2012年(17)

我的朋友

分类: 其他平台

2014-04-01 14:50:21

今天去面试被问到了单例模式,我很得意的写了下来,以为万无一失,结果发现我错了,我有两点没有考虑到。
(1)这个类要确定不能在其它类中new出来实例对象出来,该怎么办呢?
     就要写一个私有的构造方法,这点很重要。

  1. private SingleMode() {
  2.         
  3.     }

(2)在整个应用程序中只能有一个实例:
     我之前是这么写的:
     这样的话,可以判定是否为空,为空就新建一个实例,不为空,就返回之前的。
        
  1. public static SingleMode mInstance() {
  2.         if (single==null) {
  3.             single=new SingleMode();
  4.         }
  5.         return single;
  6.     }

(3)后来问题又来了,如果有两个线程同时调用我这个方法该怎么办呢?那么有可能会生成两个新的实例。

     那么,我们要做的是,在同一时刻只能保证一个线程生成一个新的实例。
     怎么办好呢,加上同步锁吧,于是我做了如下改进:

  1. public static SingleMode getInstance() {
  2.         synchronized (SingleMode.this) {
  3.             if (single==null) {
  4.                 single=new SingleMode();
  5.             }
  6.         }
  7.         return single;
  8.     }

(4)这样的话确实可以保证同一时刻,只有一个线程可以生成一个实例,但是问题又来了,我给这个类加的同步锁,
     也就是说同一时刻,只有一个线程访问这个类的方法,

     其他线程就不能访问这个单例类的其它方法了,如果再改成下面的方法是否可行呢?

  1. public synchronized static SingleMode mInstance() {
  2.         if (single==null) {
  3.             single=new SingleMode();
  4.         }
  5.         return single;
  6.     }

(5) 这样的话,对方法加上同步锁,能保证在同一时刻只能有一个线程调用这个方法,但是问题又有了,

      某一个时刻,只能有一个线程获得这个实例,如果有多个线程则要等待,这样的话会影响到程序的性能。
      那么我再改进一下,可以把这个同步方法再做一次判断,这样的话,
      就不用担心每次只有一个线程获得它所在的实例了
代码如下:

  1. public static SingleMode getInstance() {
  2.         if(single==null) {
  3.             return mInstance();
  4.         }
  5.         return single;
  6.     }

  7.     
  8.     public synchronized static SingleMode mInstance() {
  9.         if (single==null) {
  10.             single=new SingleMode();
  11.         }
  12.         return single;
  13.     }

(6)好了,在不断的改进中,最后还是完成了,就觉得自己想问题还是不够完善,才会没有考虑得更加清楚

    完整版的单例模式如下,在网上我没有看到这样的,所以我希望能分享出来,
    不管是面试还是以后的编码中对大家都有帮助。


  1. public class SingleMode {

  2.     private static SingleMode single = null;
  3.     
  4.     // (1) 私有的构造方法
  5.     private SingleMode() {
  6.         
  7.     }

  8.     public static SingleMode getInstance() {
  9.         if(single==null) {
  10.             return mInstance();
  11.         }
  12.         return single;
  13.     }

  14.     
  15.     public synchronized static SingleMode mInstance() {
  16.         if (single==null) {
  17.             single=new SingleMode();
  18.         }
  19.         return single;
  20.     }
  21. }

总结:通过这次对单例模式的补充,越发觉得自己有太多需要补充的地方,分享给大家,希望对大家有帮助。

PS:注意细节,细节决定成败。
阅读(562) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~