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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© jk7130866 中级黑马   /  2015-7-20 21:25  /  460 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

   今天学习到java视频的第六天单例类,单例类的两种实现形式:一,饿汉式这种方式是在实际开发中常用的,比较安全,而且简单,来看看例子

class Single
{
private Single();//私有化构造函数,让别别人无法创建是、该类的实例。
private static Single s=new Single();
//定义一个私有静态 Single类的引用,并创建一个实例,这里对我的理解是,当类载入内存,静态的成员同事创建,而且至执行一次。所以只有一个实例。
public static Single getInstance()//定义一个共有的静态方法,让外部能够获得,这个实例。
{
   return s;
}
}
就这样就可以实现单列类了,当然着个类没什么功能,你想让他鱼油什么样的属性都可以加进去了,当然也可加各种方法。
二,懒汉式;
懒汉式在实际开发中不常用,看看他是怎么实现的。
class Single
{
private Single();//私有化构造函数,让别别人无法创建是、该类的实例。
private static Single s;
//定义一个私有静态 Single类的引用,与饿汉式不同的地方是,并不创建对象,而是在获取的方法创建,就是延时创建。
public static Single getInstance();//定义一个共有的静态方法,让外部能够获得,这个实例。
{
if(s==null){
s=new Single();
}
   return s;
}
}

懒汉式也实现了。但这样实现有点小问题,因为创建对象是先判断再创建,当有多个线程都来获得这个实例的时候,有可能出现问题,例如有两个线程分别是A和B,当A调用getInstance(),是恰好执行到判断语句if(s==null)这是还没有对象,正准备创建对象,但CPU恰好切换了线程,A被挂起来,接B当A调用getInstance(),此时s==null,因为A 并没创建,那B 线程就自己创建了,CPU切换回A 的时候,继续执行创建的语句,有创建了一次对象。问题出现了吧,
那怎么解决呢,也很简单在getInstance()前加上同步锁synchronized,既可以了
public static synchronized Single getInstance();

{
if(s==null){
s=new Single();
}
   return s;
}
因为加了锁所以就算CPU切出去,B也进不来,先判断有没有别的线程在调用这个方法,A在调没返回之前,B进不来。但这样虽然可以的但比较低效因为每次调用getInstance()方法都要先判断有没有别的线程在调用,可以优化一下,就是双重判断当调用getInstance()方法先判断s是否为空,如果为空在加锁,这样如果不为空的话就直接返回S 。不用再加锁了。
今天学习完,了把自己理解写下来,有理解错误的希望大家指正。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马