黑马程序员技术交流社区

标题: 加synchronized 与不加有什么区别 [打印本页]

作者: 明锦添    时间: 2013-3-18 23:00
标题: 加synchronized 与不加有什么区别
public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {
  //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次    
  //使用时生成实例,提高了效率!
  if (instance==null)
    instance=new Singleton();
  return instance;   }

}


有时候我没加synchronized 关键字,加了与不加有什么区别吗.请问

作者: 邹铭钰    时间: 2013-3-18 23:17
如果两个线程运行这个,不加synchronized的话,有可能一个线程运行到if(instance==null)后,退出cpu,另一个线程进入cpu,这时instance还是==null,这个if成立,这样两个线程都成立则生成了两个对象。
作者: 朱盛文    时间: 2013-3-18 23:31
synchronized 是同步锁,加上就避免了多线程运行的不安全。
当多个线程同时操作多条语句的共享数据时,就会出现不安全性。
if (instance==null)
          ————>假如A线程运行到这,停住了,然后B线程也进来了,new 了一个Singleton,接下来A醒了,又new了一个Singleton,就导致了线程的不安全
    instance=new Singleton();
加了同步锁后,每次进入判断if之前,就先判断一下里面有没有线程在运行,没有才进入if判断。当第一个线程进入后,就拿了锁,第二个线程一过来,判断有锁就进不来了
作者: 黑马17期-闫东东    时间: 2013-3-19 00:06
synchronized同步锁,解决线程的安全问题,如果不加程序可能出错,例如:当A线程判断 s==null  后,没来得及new  对象就挂起,线程B判断为null,new  对象,A恢复,不在判断就new对象,就出错了。同步保证只用一个对象访问资源。
懒汉式:
class Single{
        private Single (){};
        private static Single s=null;
        public static Single getInstance()
        {
                        if(s==null)
                        {
                                synchronized(Single.class)
                                {
                                        if(s==null)
                                        {
                                                s=new Single();
                                        }       
                                       
                                }
                        }
                return  s;
        }
}
作者: HM赵磊    时间: 2013-3-19 00:07
本帖最后由 HM赵磊 于 2013-3-19 00:08 编辑

这个问题分为两点解释:
一、由于JAVA对多线程的支持,当多个线程对共享数据进行操作时,如果不加以限制将会出现数据错乱,这时synchronized就派上用场了,她给多个线程要操作的共享数据加了一把锁,任何线程对共享数据操作时,会给数据加一把锁,如果锁没解开,其他的线程共享数据无法操作。那么,任何线程想要对共享数据操作的时候会先判断一下锁是否存在,这样就保证了数据的安全性,一致性。
二、您给出的例子是单例设计模式中的懒汉式。如果不使用synchronized修饰的话,假设有两个线程想要获取单例对象时,同时调用了 getInstance()方法,并且这个判断if (instance==null)是正确的,就会执行instance=new Singleton(),那么就会创建了两个Singleton对象,那么单例如何保证呢?如果使用了Synchronized关键字修饰,相当于加了一把锁,调用getInstance()方法之前,会先判断有没有其他线程对其进行操作,这样就避免了并发操作,保证了单例的唯一性,正确性。





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