黑马程序员技术交流社区

标题: 黑马入学题!!! [打印本页]

作者: xiaote0225    时间: 2015-9-24 02:01
标题: 黑马入学题!!!
编写一个延迟加载的单例设计模式
作者: 李慧兵    时间: 2015-9-24 08:15

//懒汉式

class Single
{
     public static Single s=null;
     private Single(){}

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

作者: 沙鹰    时间: 2015-9-24 08:45
  1. public class Demo {
  2.        
  3.         private Demo() {
  4.                
  5.         }
  6.         private static Demo d=null;
  7.         private static Demo getDemo(){
  8.                 if(d==null){
  9.                         synchronized(Demo.class){
  10.                                 if(d==null){
  11.                                         d=new Demo();
  12.                                 }
  13.                         }                       
  14.                 }
  15.                 return d;
  16.         }
  17. }
复制代码

作者: xiaote0225    时间: 2015-9-25 23:43
沙鹰 发表于 2015-9-24 08:45

有带注释的吗?看的不太明白。谢谢啦!
作者: 善良的禽兽    时间: 2015-9-26 00:01
单例设计模式: 解决在一个类在内存中只存在一个对象;

想要保证对象唯一:
1 为了避免其他程序过多的建立该对象, 应先禁止其他程序建立该类对象;
2 还为了让其他程序能访问到该类对象, 只好在本类中, 自定义一个对象;
3 为了方便其他程序对自定义对象的访问, 可以对外提供一些访问方式;

这三部怎么用代码体现呢:
1 我们知道程序创建对象是通过构造函数, 我们只需将构造函数定义为private就可以了;
2 在类中创建一个本类对象;
3 提供一个方法获取该对象;

详细说明:
   首先我们可以自己定义一个构造函数并且将其定义为private(此时在类外便无法调用构造函数生成新的对象了), 然后我们在类中调用这个private构造函数生成一个对象, 然后问题来了, 如何让程序中的变量引用这个对象呢?   我们可以写一个函数getinstance(),返回这个对象的地址给程序中的变量, 调用类中的函数有两种方法, 一种是通过对象名来调用, 另一种是通过类名来调用, 此时我们在类外没有对象, 所以只能通过类名来调用这个函数, 想要通过类名调用, 则这个函数并需声明为static类型的, 然后static类型的函数只能访问static成员, 所以我们在类中生成的那个对象也必须声明成static类型的, 并且这个对象不被类外的其他函数直接访问, 所以把他声明成private类型的,
作者: 381890216    时间: 2015-9-26 01:01
学习大神。。。。
作者: 沙鹰    时间: 2015-9-26 10:38
xiaote0225 发表于 2015-9-25 23:43
有带注释的吗?看的不太明白。谢谢啦!
  1. public class Demo1 {
  2.         // 将构造方法私有,使外界不能创建对象
  3.         private Demo1() {

  4.         }

  5.         // 将变量d用static修饰以便在getDemo()中调用,为其赋值为null,以便实现延迟加载
  6.         private static Demo d = null;

  7.         // 给外界提供一个得到当前类的对象的方法,用static修饰,以便通过类名直接调用
  8.         private static Demo getDemo1() {
  9.                 if (d == null) {
  10.                         //上锁,使其一次只能进去一个
  11.                         synchronized (Demo1.class) {
  12.                                 //再次判断d是否为空,若为空就将当前类所new的对象赋值给d
  13.                                 if (d == null) {
  14.                                         d = new Demo();
  15.                                 }
  16.                         }
  17.                 }
  18.                 return d;
  19.         }
  20. }
复制代码

作者: Synaric    时间: 2015-9-26 12:13
以2L代码为例,我想你知道懂同步块,但是看不懂为何判断s==null两次吧
同步块内部的s==null判断是因为外部的s=null判断并不是线程同步的,很可能线程1在执行同步块内部的语句时,线程2已经new了一个s。同步块外面的s==null语句是为了避免同步块的开销,毕竟s已经创建了,如果每次访问s都需要在同步块内判断s==null是不值得的开销。
作者: a8336675    时间: 2015-9-26 13:32
学习学习~
作者: SuperApollo    时间: 2015-9-26 13:34
懒汉式。。。。。。。。
作者: 乱世心    时间: 2015-9-26 18:54
呃呃  好好学习吧
作者: 纳木错的程序猿    时间: 2015-9-26 23:54
高手还是多。




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