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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 范泰洋 高级黑马   /  2012-10-12 00:59  /  1093 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

设计模式:解决某一类问题最行之有效的方法。

Java中有23中设计模式。
单例设计模式:解决一个类在内存中只存在一个对象。

想要保证对象唯一。(原理解释部分)
为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象。
还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
为了方便其他程序自定义对象的访问,可以对完提供一些访问方式。

三个步骤代码体现
构造函数私有化。{当我们new一个对象时,需要调用相对应的构造函数对本类对象实例化,才能在堆内存空间开辟空间。但是我们把构造函数私有化的话,由于外部是不能访问到私有后的内部成员的。这时候我们就不能创建对象了。}
在类中创建一个本类对象。{虽说我们对构造函数进行了私有化了不能创建对象了,但是由于单例设计模式是保证一个类中只存在一个对象的。所以我需要在本类自己创建一个本类对象。}
提供一个方法可以获取到该对象。{提供了一个获取本类对象的方法,方便于外部通过这个方法获取到本类对象。}

饿汉式:类一加载就初始化对象。
Class Single{
        Private Single(){};
        Private static Single s = new Single();
       
        Public static Single getInstance(){
        Return s;
        }
}


懒汉式:方法被调用的时候才初始化,也叫做对象的延时加载。
Class Single{
        Private Single(){};
        Private static Single s = null;
       
        Public static Single getInstance(){
        If(s==null){
       
        S = new Single();
        Return s;
        }
        }
}

饿汉式特点:Single类一进内存,就已经创建好了对象。{Single类一进内存进行加载的时候,这时候堆内存中开辟了一个空间创建好了一个对象。并把对象的内存地址值赋值给了变量s。为什么这个对象会随着类的加载进行创建对象呢?因为它被static关键字所修饰,根据static的特点来解释,被static关键字所修饰的变量是随着类的加载而加载的。}


懒汉式的特点:Single类进内存,对象还没有存在,只用调用了获取对象方法时,这时才建立对象。{Single类进内存的时候,没有立即创建对象,只有调用获取对象方法的时候才创建对象。}


饿汉式出现并发访问问题的解决方案:|||但是不是最优的!
class Single2{
        private Single2(){};
       
        private static Single2 s2 = null;
        public static Single2 getSingle2(){
                --->c当a释放返回了对象,释放了手中的锁,c就要进来了,但是发现s2已经不为null,条件不满足。
        if(s2==null){
        --->b判断s2为null试图想要拿到锁,但是条件不满足。
                                synchronized(Single2.class) {//这个编译生成的文件是唯一的,用这个来做一把锁。
                                        if(s2==null){//当a和b同时调用这个方法的时候,假如a条件都满足了拿到了锁,突然睡着了,这时b就会试图想要拿锁,但是这时锁还在a的手里,a还没有释放手中的锁,所以进不来。
        --->a手中拿着single.class这把锁。
                                                s2 = new Single2();
                                        }
                                }
                        }
                        return s2;//当a创建了对象并返回了,就会释放手中的锁,这时b拿到了锁,但是经过判断,s2已经指向了一个对象,已经不为null了,所以不会在创建对象了。当c进来的时候经过判断s2不为null了,就不满足条件了连判断锁都省去了!
                }
}

public class SingleDemo2 {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
               
                Single2 s1 = Single2.getSingle2();
                Single2 s3 = Single2.getSingle2();
               
                System.out.println(s1.equals(s3));
               
        }

}

记住原则:定义单例,最好使用饿汉式。

评分

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

查看全部评分

0 个回复

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