Java 单例模式探讨

Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦。

 

总结一下我所知道的单例模式实现方式:

 

1.预先加载法

 

class S1 {
    private S1() {
        System.out.println("ok1");
    }


    private static S1 instance = new S1();

    public static S1 getInstance() {
        return instance;
    }
}

 

优点:  

1.线程安全的

2.在类加载的同时已经创建好一个静态对象,调用时反应速度快。

缺点: 资源利用效率不高,可能getInstance永远不会执行到,但是执行了该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化了

 


2.initialization on demand,延迟加载法  (考虑多线程)

 

class S2 {
    private S2() {
        System.out.println("ok2");
    }

    private static S2 instance = null;

    public static synchronized S2 getInstance() {
        if (instance == null) instance = new S2();
        return instance;
    }
}

 

优点: 资源利用率高,不执行getInstance就不会被实例,可以执行该类其他静态方法。


缺点: 第一次加载时发应不快  ,多线程使用不必要的同步开销大

 

3.initialization on demand double check 双重检测( 考虑多线程 )

 

class S3 {
    private S3() {
        System.out.println("ok3");
    }

    private static S3 instance = null;

    public static S3 getInstance() {
        if (instance == null) {
            synchronized (S3.class) {
                if (instance == null)
                    instance = new S3();
            }
        }
        return instance;
    }
}

 

优点: 资源利用率高, 不执行getInstance就不会被实例,可以执行该类其他静态方法。


缺点: 第一次加载时发应不快  ,由于java 内存模型一些原因偶尔会失败

 


4.initialization on demand holder  (考虑多线程)

 

class S4 {
    private S4() {
        System.out.println("ok4");
    }

    private static class S4Holder {
        static S4 instance = new S4();
    }


    public static S4 getInstance() {
        return S4Holder.instance;
    }
}

 

优点: 资源利用率高, 不执行getInstance就不会被实例,可以执行该类其他静态方法。


缺点: 第一次加载时发应不快

 

 

 

总结: 一般采用 1 即可,若对资源十分在意也可考虑 4 ,不要使用2,3了。

 

 

测试代码:(暂不探讨Class.forName类加载机制)

 

/**
 * Created by IntelliJ IDEA.
 * User: yiminghe
 * Date: 2009-6-8
 * Time: 19:20:52
 */
public class Singleton {
    public static void main(String[] args) throws Exception{
        System.out.println(Class.forName("S1"));
        System.out.println(Class.forName("S2"));
        System.out.println(Class.forName("S3"));
        System.out.println(Class.forName("S4"));
    }
}

/*
    预先加载法
    优点:1.线程安全的,
          2.在类加载的同时已经创建好一个静态对象,调用时反应速度快。

    缺点: 资源利用效率不高,可能这个单例不会需要使用也被系统加载
 */
class S1 {
    private S1() {
        System.out.println("ok1");
    }


    private static S1 instance = new S1();

    public static S1 getInstance() {
        return instance;
    }
}

/*
    initialization on demand,延迟加载法  (考虑多线程)
    优点:1.资源利用率高
    缺点:第一次加载是发应不快  ,多线程使用不必要的同步开销大

 */
class S2 {
    private S2() {
        System.out.println("ok2");
    }

    private static S2 instance = null;

    public static synchronized S2 getInstance() {
        if (instance == null) instance = new S2();
        return instance;
    }
}


/*
    initialization on demand - double check 延迟加载法改进之双重检测  (考虑多线程)
    优点:1.资源利用率高
    缺点:第一次加载是发应不快  ,由于java 内存模型一些原因偶尔会失败

 */
class S3 {
    private S3() {
        System.out.println("ok3");
    }

    private static S3 instance = null;

    public static S3 getInstance() {
        if (instance == null) {
            synchronized (S3.class) {
                if (instance == null)
                    instance = new S3();
            }
        }
        return instance;
    }
}


/*
   initialization on demand holder  (考虑多线程)
   优点:1.资源利用率高
   缺点:第一次加载是发应不快

*/
class S4 {
    private S4() {
        System.out.println("ok4");
    }

    private static class S4Holder {
        static S4 instance = new S4();
    }


    public static S4 getInstance() {
        return S4Holder.instance;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值