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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张秀威 中级黑马   /  2013-10-31 19:21  /  1428 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张秀威 于 2013-11-1 09:46 编辑

下面是饿汉式和懒汉式的代码,问题标注在代码中了,谢谢
/*
* 以下是单例设计模式之一:饿汉式:这个是先初始化对象的。-----student类一进内存,就已经创建好了对象。
*/
        
        private int age;
        private static student s=new student();
        private student(){};
        public static student getStudent()
        {
                return s;
        }
        public void setAge()
        {
                this.age=age;
        }
        public int getAge(int age)
        {
                return age;
        }
/*
* 以下代码是单例设计模式之二,懒汉式:对象是方法被调用时,才初始化的。也叫做对象的延时加载。
* ------student类一进内存,对象还没有存在,只有调用了getStudent方法时,才建立对象的!!!!!
*/
        /*private int age;
        private static student s=null;
        private student(){}
        public static student getStudent()
        {
                if(s==null)
                                       Synchronized(Student.class)//还有这里,这个锁可以放到其它地方吗,这个调用class又怎么理解呢??
                                      {
                             s=new student();
                             return s;
                                       }
        }
        public void setAge()
        {
                this.age=age;
        }
        public int getAge(int age)
        {        
                return age;
        }*/
}        
public class seJiMoShi {

        public static void main(String[] args) {
                student s1=student.getStudent();//我想问的是s1和s2同一个对象吗
                        student s2=student.getStudent();//
                                System.out.println(s1.getAge(23));
                System.out.println(s2.getAge(23));
        }
}
        

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1 注意细节哦!

查看全部评分

4 个回复

倒序浏览
第一个:锁是为了防止多个线程因为时间差都进入了if(s==null)块中而产生多个实例,放其他地方那要看你要实现什么样的目的,范围可以扩大,但不推荐
class是说这个一个类锁,凡是调用Student这个类时都会被阻塞等待钥匙,原因是这是一个静态方法,是通过类直接调用的
第二个:自然是同一个对象,单例模式不就是通过静态方法返回同一实例么
通过s1 setAge,然后s2 getAge获得的是刚刚设置的年龄
另外,你的代码错误:懒汉式getStudent方法if块外面也要有返回值,set方法需要参数,get方法不需要参数

评分

参与人数 1技术分 +1 收起 理由
周志龙 + 1 赞一个!

查看全部评分

回复 使用道具 举报
  1. public static student getStudent()
  2.         {
  3.                 if(s==null)
  4.                                        Synchronized(Student.class)//还有这里,这个锁可以放到其它地方吗,这个调用class又怎么理解呢??
  5.                                       {
  6.                              s=new student();
  7.                              return s;
  8.                                        }
  9.         }
复制代码
现在来看这个静态函数,我们知道,锁可以是任意对象,但是呢,既然是单例,我们就要保证对象的唯一,即也要保证锁的唯一,如果锁不一致的话,那约束我创建对象的提交都不一致了,得到的对象肯定是不一致的!
现在来看这个锁应该是谁比较合适呢,静态方法中锁,显然没法用this吧,有静态的时候还没有this呢吧?那么我们去创建其他对象,比方来一个new Object();那么这样的结果是什么呢?是我妹调用一次getStudent(),就在内存中创建一个Object对象,这个锁不一致了吧,没有达到约束对象唯一的条件了吧,那么在java中,给我们提供了一个唯一的东西是什么呢?就是.class文件,无论我们创建多少给Student对象,我们是不是都是用的同一个.class文件来创建的呀,那么好,有了这个唯一了,怎么把它搞成对象了,java就有给我们提供了一个Class对象,简单的理解为把.class文件搞成对象,即字节码文件,在静态方法上加的锁也是这个字节码,正是因为.class文件的唯一,导致了字节码的唯一,所以在这里只能用Student对应的字节码Student.class作为所对象。
你就可以理解为 类名直接调用自己的一个属性(class),其返回值是一个对象,O了。


那么显然,你在下面的问题就迎仍而解了,既然对象都是同一个,只是我在不同的阶段起的名字(引用)不一样而已嘛,其在内存中还是同一 一个东东吧,所以必须是同一个对象。
当然,这种懒汉式的写法有点效率低下,可以加一个双重判断,来提高一下下:
  1. public static student getStudent()
  2. {
  3.         if(s==null) {
  4.                 synchronized(Student.class)//还有这里,这个锁可以放到其它地方吗,这个调用class又怎么理解呢??
  5.                 {
  6.                 if(s == null)
  7.                         s=new student();
  8.                 }
  9.         }
  10.         return s;
  11. }
复制代码
楼主好几个错误呀,synchronized首字母是小写呀~~,被同步的代码必须要写在synchronized(。。){被同步的代码},楼主没有{}个呀,没报错吗,我记得不加{}会报错的~

希望对楼主有用~

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
零下五度的水 发表于 2013-10-31 20:45
第一个:锁是为了防止多个线程因为时间差都进入了if(s==null)块中而产生多个实例,放其他地方那要看你要实 ...

是哦我大意了
回复 使用道具 举报
喂,咱不离! 发表于 2013-10-31 20:45
现在来看这个静态函数,我们知道,锁可以是任意对象,但是呢,既然是单例,我们就要保证对象的唯一,即也要 ...

呵呵,谢啦,因为有些是手动打的,确实疏忽了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马