A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何清林 中级黑马   /  2014-3-8 00:49  /  6516 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

懒汉式有什么弊端,怎么避免呢?

12 个回复

倒序浏览
就是同步问题,   如果多个线程获取对象,可能会获取不同的引用。  对获得对象的方法加上synchronized  保证不会出现不同的引用
回复 使用道具 举报
当遇到线程时  有可能不是单例模式啦   应该是代码同步  在方法上加synchronized 不是最佳的方法  下面是最佳的方法  双重判断
  1. public class Single2 {  
  2.       private static Single2 ss = null;  
  3. private Single2(){  
  4.     }  
  5.     public static Single2 getIntance(){  
  6.         if(ss == null){  
  7.             synchronized(Single2.class){  
  8.                 if(ss==null){  
  9.                     ss = new Single2();  
  10.             }  
  11.                   
  12.       }  
  13.               
  14.        }  
  15.            return ss;  
  16.     }  
  17. }
复制代码


评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
饿汉式单例
  1. public class Singleton
  2. {
  3.       private static final Singleton SINGLETON = new Singleton();
  4.       private Singleton() {} //此类不能被实例化
  5.       public static synchronized Singleton getInstance() {
  6.       return SINGLETON;
  7. }
复制代码

优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
饿汉式无需关注多线程问题、写法简单明了、能用则用。但是它是加载类时创建实例(上面有个朋友写错了)、所以如果是一个工厂模式、缓存了很多实例、那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。懒汉式的优点是延时加载、缺点是应该用同步(想改进的话现在还是不可能,比如double-check)、其实也可以不用同步、看你的需求了,多创建一两个无引用的废对象其实也没什么大不了。

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
问题应该说清楚点。懒汉式跟饿汉式的区别在与对象是否加载,取决于是否使用。硬要说弊端就是在使用时才会有对象。
回复 使用道具 举报
懒汉式中有对象的延时加载,可能不同的线程会在等待唤醒期间建立多个对象,这不符合单例设计模式。可以加同步synchronized来解决,加同步时用的锁是该类所属的字节码文件对象,但是当线程很多时,每个线程都要判断锁,所以懒汉式在运行时比较低效。可以用双重判断的方式来解决问题,第一次判断后,以后进来的线程都不用判断了,会稍微提高效率。即
  1. class Single{
  2.      private static Single s = null;
  3.      private Single() {}
  4.      public static Single getInstance(){
  5.            if(s==null)
  6.            {
  7.                   synchronized(Single.class)
  8.                   {
  9.                          if(s==null)
  10.                               s=new Sinlge();
  11.                    }
  12.             }
  13.       }
  14. }
复制代码



评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
syw02014 发表于 2014-3-8 09:33
饿汉式单例

优点:没有加锁,执行效率会提高。

明白了,谢谢
回复 使用道具 举报
懒汉式单例,存在线程安全问题,可以加同步synchronized来解决,但是同步带来效率下降,在懒汉式单例中再加个if判断可以提高了同步带来的效率低问题,代码如下:
  1. public class Single {
  2.         private static  Single s=null;
  3.         private Single(){}
  4.         public static Single getInstance(){
  5.                 if (s==null) {
  6.                         synchronized (Single.class) {
  7.                                 if (s==null)
  8.                                         s=new Single();
  9.                         }
  10.                 }
  11.                 return s;
  12.         }
  13. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
MVP 中级黑马 2014-3-8 17:09:16
9#
懒汉式的弊端就是线程安全问题,如果要避免有两种方法:
1.在获取对象的方法中加入synchronized
2.双重判断。并在第二重判断中加入synchronized。

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
所谓的单例就是一个类只能创建一个实例 所谓懒汉模式就是说不管你是否来取实例,我都一早给你创建好,等你来取 所谓饿汉模式就是说之前不一定已经创建好实例,你来取实例的时候我先检查是否存在实例,存在就返回给你,不存在就new一个给你
回复 使用道具 举报
晕,没看毕姥爷的视频吗???他老人家强调了好多次阿,亲!!!;懒汉式可以提高运行效率,在没有调用时不会加载对象,只有在调用对象时才会创建并调用对象!!但这也有一个问题,那就是遇到多线程时会遇到安全问题,因此可以采用两个if判断的方式来避免这种情况!!代码如下
     class Single {
        private static  Single s=null;
        Object obj=new Object();//上帝嘛,你懂的
        private Single(){}
        public  Single getInstance()
             {
                if (s==null)
                       {
                        synchronized (obj)
                            {
                                if (s==null)
                                       s=new Single();
                           }
                   }
                   return s;
        }
}

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
kira 中级黑马 2014-3-10 12:37:24
12#
tangxiaobo1991 发表于 2014-3-10 00:49
晕,没看毕姥爷的视频吗???他老人家强调了好多次阿,亲!!!;懒汉式可以提高运行效率,在没有调用时不 ...

哈哈 哥们儿略激动 不过锁太多的话有可能造成死锁哦 这个我看上面都没有提到过:lol
回复 使用道具 举报
  1. class Single
  2. {
  3.         private static Single s = null;
  4.         private Single(){}
  5.         public static Single getInstance()
  6.         {
  7.                 if(s==null)
  8.                 {
  9.                         synchronized(Single.class)
  10.                         {                               
  11.                                 if(s==null)
  12.                                         s = new Single();
  13.                         }
  14.                 }
  15.                 return s;
  16.         }
  17. }

  18. //定义单例,建议使用饿汉式。
  19. //简单,容易记下,还不容易发生问题




  20. class Single
  21. {
  22.         private static Single s = new Single();
  23.         private Single(){}
  24.         public static Single getInstance()
  25.         {
  26.                 return s;
  27.         }
  28. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马