黑马程序员技术交流社区

标题: 并发访问单例懒汉式是否有问题?怎么解决? [打印本页]

作者: 刘海源    时间: 2012-7-22 18:58
标题: 并发访问单例懒汉式是否有问题?怎么解决?
class Single
    {
         private Single s=null;
         private Single(){}
         public Single getInstance()
         {
           if(s==null)
             {
                 synchronized(Single.class)
               {
              if(s==null)
                 s=new Single();
                }
              }
             return s;
         }
     }
求解释为什么会这样,
作者: 黑马-王言龙    时间: 2012-7-22 19:15
并发访问单例懒汉式是否有问题?
答:1、多线程中,单例懒汉式有安全问题。
假如有一个线程进来判断s是否为空,结果s==null准备去给s赋值;这时,第二个线程切换进来执行,将s赋值后,第一个线程又将s赋值,覆盖了第二个线程的操作,就会出现安全问题。

怎么解决?
2、用同步代码块和同步函数都能解决此问题,但效率稍低;
可以用双重判断来减少判断锁的次数。当一个线程拿到“锁”后,将对s赋值,第二线程没有“锁”,所以不能给s赋值,当第一个线程赋值成功后,第二个线程会发现s!=null,所以再次赋值操作不会发生,安全问题得以解决,而且下次再有线程进入时,就不会再判断锁,只判断第一个s是否null的条件即可 。效率提高了。
作者: 李伟    时间: 2012-7-22 19:27
              synchronized(Single.class)/*当多个线程执行该程序时,CPU是切换执行的,懒汉单例模式需要在这加上synchronized(Single.class)这条
                                  语句,保证当一个线程在访问这段程序时,其他线程进不来,如果不加这条语句的话,当第一个线程执行到下面
                                 if(s==null)语句和s=new Single()语句之间时CPU切换到另一个线程执行,那么另一个线程也能通过if(s==null)这条
                                 语句,可能会导致多个线程执行s=new Single()语句,从而创建了多个对象,也就不是单例了,进而造成了安全隐患*/
               {
              if(s==null)
                 s=new Single();
                }

作者: 陈世涛    时间: 2012-7-22 19:36
在被多线程并发访问时,会出现多线程安全问题。

为了解决,加入了同步,虽然安全问题解决了,
但是性能降低了。
有没有办法将安全问题解决的同时,还可以提高性能。

有的,改成同步代码块。
可以通过双重判断的形式来完成这个过程。


class Single
{
        private static Single s = null;
        private Single(){}
        public static  Single getInstance()
        {
                if(s==null)
                {
                        synchronized(Single.class)
                        {
                                if(s==null)
                                s = new Single();
                        }
                }
                return s;

        }
}
class SingleDemo
{
        public static void main(String[] args)
        {
                System.out.println("Hello World!");
        }
}
希望对楼主有帮助,




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2