java设计模式--单列模式

来源:互联网 发布:淘宝不属于广告商品 编辑:程序博客网 时间:2024/05/03 02:53
java设计模式--单列模式

单列模式定义:确保一个类只有一个实例,并提供一个全局访问点。

下面是几种实现单列模式的Demo,每个Demo都有自己的优缺点:

Demo1:

复制代码
/** * 单列模式需要满足下面三个条件: * 1.私有的构造函数 * 2.私有的引用变量 * 3.公开的静态方法(唯一获取该类单个实例的地方) *  * @author Administrator */public class AmericaPresident{    private static AmericaPresident thePresident;        /**     * 功能:私有的构造函数     */    private AmericaPresident()    {    }        /**     * 功能:返回AmericaPresident对象     * @return     */    public static AmericaPresident getPresident()    {        if(thePresident == null)        {            thePresident = new AmericaPresident();        }                return thePresident;    }}Demo1 在多线程的时候可能会出现一些程序上的bug
复制代码

Demo2:

复制代码
为了解决上面Demo1在多线程时候的bug,可以做出以下的修改:/** * 单列模式需要满足下面三个条件: * 1.私有的构造函数 * 2.私有的引用变量 * 3.公开的静态方法(唯一获取该类单个实例的地方) *  * @author Administrator */public class AmericaPresident{    private static AmericaPresident thePresident;        /**     * 功能:私有的构造函数     */    private AmericaPresident()    {    }        /**     * 功能:返回AmericaPresident对象     * @return     */    public static synchronized AmericaPresident getPresident()    {        if(thePresident == null)        {            thePresident = new AmericaPresident();        }                return thePresident;    }}通过增加synchronized 关键字到getPresident()方法中,我们迫使每个线程在进入这个方法之前,要先等候别的线程离开该方法。也就是说,不会有两个线程可以同时进入这个方法。Demo2解决了多线程下的程序bug,但是又带了一个新的问题,同步一个方法可能造成程序执行效率下降100倍。
复制代码


Demo3:

复制代码
/** * 单列模式需要满足下面三个条件: * 1.私有的构造函数 * 2.私有的引用变量 * 3.公开的静态方法(唯一获取该类单个实例的地方) *  * @author Administrator */public class AmericaPresident{    private static AmericaPresident thePresident = new AmericaPresident();        /**     * 功能:私有的构造函数     */    private AmericaPresident()    {    }        /**     * 功能:返回AmericaPresident对象     * @return     */    public static synchronized AmericaPresident getPresident()    {        return thePresident;    }}Demo3使用"急切"创建实例,而不用延迟实例化的做法,如果应用程序总是创建并使用单列实例,或者在创建和运行方面的负担不太繁重,就可以用"急切"的方法来创建单列。利用这个做法,我们可以依赖JVM在加载这个类时马上创建此唯一的单列实例,JVM保证在任何线程访问thePresident静态变量之前,一定先创建此实例。
复制代码


Demo4:

复制代码
用"双重检验加锁",在getPresident()中减少使用同步。利用双重检查加锁(double-checked locking),首先检查是否实例已经创建了,如果尚未创建,"才"进行同步。这样一来,只有第一次会同步。/** * 单列模式需要满足下面三个条件: * 1.私有的构造函数 * 2.私有的引用变量 * 3.公开的静态方法(唯一获取该类单个实例的地方) *  * @author Administrator */public class AmericaPresident{    private volatile static AmericaPresident thePresident;        /**     * 功能:私有的构造函数     */    private AmericaPresident()    {    }        /**     * 功能:返回AmericaPresident对象     * @return     */    public static synchronized AmericaPresident getPresident()    {        if(thePresident == null)//检查实例,如果不存在,就进入同步区块        {            synchronized(AmericaPresident.class)//注意,只有第一次才彻底执行这里的代码            {                if(thePresident == null)//进入区块后,再检查一次,如果还是Null,才创建实例。                {                    thePresident = new AmericaPresident();                }            }        }        return thePresident;    }}volatile关键字确保:当thePresident变量被初始化成AmericaPresident实例时,多个线程正确处理thePresident变量。如果性能是你关注的重点,那么这个做法可以帮你大大地减少getPresident()的时间消耗。
复制代码

 

0 0
原创粉丝点击