黑马程序员——多线程和单例设计模式

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流!----------------------

 

Java程序员在编写程序时,为了满足某些需求,对特定的需求会有特定的程序编写格式,这就是设计模式。Java中常见的设计模式有23种,比如工厂设计模式,代理设计模式等等。单例设计模式也是常见的设计模式之一,它是用来满足一个类在内存只存在一个对象的需求。

要保证对象唯一要满足以下几点:

1.为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象

2.为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。

3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

 

以上三点怎么用代码体现呢?

1.将构造函数私有化。

2.在类中创建一个本类对象。

3.提供一个方法可以获取到该对象。

其实对于所有的事物对象,当它需要保证在内存中唯一时,加上以上三步即可。

对于单例设计模式来说,它又分为两种情况,一种是饿汉式,一种是懒汉式。

饿汉式,先初始化对象。如下,Single类一进内存,就已经创建好了对象。

class Single{

    privateSingle(){}//私有化构造函数。

    privatestatic Single s = new Single();//创建Single对象。

    publicstatic Single getInstance(){//提供方法使得外界可以获取该对象。

       return s;

    }

}

懒汉式,对象是方法被调用时才初始化,也叫做延时加载。Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。

class Single{

  private static Single s = null;//先不初始化。

  private Single(){}

  public static Single getInstance(){

     if(s==null)//判断s是否为null,是即初始化。

        s = new Single();

     return s;

   }

}

从以上两种方式,我们可以看出懒汉式会比饿汉式对于内存优化方面更有优势,因为它是需要时才加载,减少了对内存的浪费。但是懒汉式延时加载会存在安全问题,当有多线程访问时,如果前一个线程访问到if(s==null)这句代码,判断s为null,然后在执行初始化对象时线程暂时停止了,这时有另一个线程进行if(s==null)的判断,也是为true的,也会执行初始化语句。那么,等到前一个线程继续执行,其实内存中会存在不只一个Single对象。

所以,我们需要对懒汉式进行安全问题处理,可以加同步代码块或者同步函数。从代码可以看出操作共享数据的代码就是if(s==null)和s= new Single()这两句代码。可以将这两句代码放进同步代码块中,即

synchronized(Single.class){//这里要注意使用的锁是该方法所在类的字节码文件对象                    

    if(s==null)

        s = new Single(); }

但是这样做了之后,每个线程要继续判断锁,不管s是否已经被初始化了,这样会使得效率变低。为了解决效率低下的问题,可以在同步代码块之前加多一个判断语句,判断s是否已经被初始化,如果已经被初始化了,就可以直接跳过判断锁的语句了。即

if(s==null){

  synchronized(Single.class){

      if(s==null)

        s = new Single();

  }

}

return s;

利用双重判断的方式就可以解决效率问题啦。

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流!----------------------

 详细请查看:http://edu.csdn.net

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值