“戏”说设计模式——单例模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wfy2695766757/article/details/85213384

首先请出今天的主人公——“心灵港湾”家人

每逢过节,大家都会拜访长辈,走亲访友。尤其到了过年的时候,每家每户都是热热闹闹的,有的在迎接招待亲朋好友,有的在走亲串友,问候长辈。

 我们定义一个Family代表我们温馨的家

public class Family {
    private Family() {//注意这里的构造方法是私有的
    }
}

这里的构造方法是私有的,如果有:new Family();,那我们自己的家不就被别人窃取了吗?所以要定义成私有的private,我们自己的家,我们自己创造,别人无权“创造”!

我们自己的家,家中的一切都是我们自己家人说了算,别人的言语我们只是听一听,所以家只能由家人创造。

public class Family {
    private static final Family family = new Family();//自己的家人自己“守护”
    private Family() {//注意这里的构造方法是私有的
    }
}

以上private关键字保证了家人的私有性不可见性不可访问性,我们要保护自己的家人。static关键字保证家人的静态性,它与类同在,不依赖于类的实例化就自有永有,它将在内存中永生,GC垃圾回收器也回收不了他。final关键字则保证家人是和常量,衡量一样,不会被其他人改变。(每天“面向对象”的你,创造了千千万万的对象,但是家人是不可能永生的,也不能被随时创造,所以趁现在多陪陪家人吧!!!

接下来,就到了过节走亲访友,问候长辈的环节了

public class Family {
    private static final Family family = new Family();//自己的家自己创造
    private Family() {//注意这里的构造方法是私有的
    }
    public static Family visit(){//容许亲戚朋友到家中做客
        return family;
    }
}

对于一个家庭,可以说已经构建好了,在这个家里,所有的一切将被保护,外部不能直接访问。但是留了一个公开的方法,如果有亲戚朋友要拜访我们,我们就热情招待他们,而且无论是谁拜访,肯定拜访的是一家人,这样就保证了家人在整个拜访过程中的唯一性。

在上面的例子中,我们直接在Family中构建了家人,这代表:当有人来拜访我们的时候,我们是在家的,没有外出,外人可以直接到家中即可见到我们,而且第二,第三波拜访的人都是可以直接到家中。这就是“懒汉方式”:指全局的单例实例在第一次被使用时构建。

但是,如果有人拜访,我们并没有到家,那岂不是误了别人的一片好心吗?那我们又将如何解决呢?

于是另一种方式应运而生, “饿汉方式”:指全局的单例实例在类装载时构建。

public class Family {
    private static Family family;//y一开始并不创建
    private Family() {//注意这里的构造方法是私有的
    }
    public static Family visit(){//容许亲戚朋友到家中做客
        if (family == null){//当客人发现家中没人时,通知主人
            family = new Family();//主人一家返到家中
        }
        return family;
    }
}

这样我们发现,一开始时,我们的主人一家并没有在家中,如果有客人拜访,客人发现家中无人自然会联系主人一家,主人一家人返家后,在进行拜访。这样做的好处:省去一段时间的内存(家中无人时)。缺点:当客人发现家中无人时,会创造主人一家,这样较痴汉模式慢一些,因为消耗了CUP去创造。

生活中也会有这样一种情况,在同一时间段内有不同的人拜访主人一家,我们要保证每一家都得到周到的招待,所以要将他们排队,所以我们使用synchronized关键字声明为同步方法,某线程调用前必须获取同步锁,调用完后会释放锁给其他线程用,也就是拜访的必须排队,拜访的客人按顺序拜访主人一家。

public static synchronized Family visit(){//容许亲戚朋友到家中做客

 这样做的好处是主人可以好好的招待客人,但是这造成了巨大时间浪费,没有充分利用CPU资源并发优势(特别是多核情况)

那我们可不可以这样想,有的客人与客人之间互相熟知,我们作为主人可以让认识的客人一起拜访(团拜思想),客人们可以一起拜访,人多就会很热闹,欢声笑语一片。

我们只对重要的客人实行单独招待。

public class Family {
    private static Family family;//y一开始并不创建
    private Family() {//注意这里的构造方法是私有的
    }
    public static Family visit(){//容许亲戚朋友到家中做客
        if (guest == "Important"){//如客人是重要客人
            synchronized (Family.class){//客人们可以一起拜访
                if (family == null){
                    family = new Family();
                }
            }
        }
        return family;
    }
}

单例模式在开发过程中有很多种延伸,我们这里讨论了最基础的两种,其实他们都各有优缺,我们要做到灵活运用,各取所需。

那么如何选择两种方法呢?现在硬件精良,内存成本很小,提前实例化有益于开发,加锁反而会导致加载时间浪费,同步效率低等问题,如果实例不是很复杂,建议使用“饿汉方式”。

系统复杂程度越高,造成的优化优化问题越多,开发风险也越高。

猜你喜欢

转载自blog.csdn.net/wfy2695766757/article/details/85213384
今日推荐