《剑指offer》面试题2:实现Singleton单例模式

题目:设计一个类,我们只能生成该类的一个实例。


思路:

1.饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法)

优点1.线程安全 。2.在类加载的同时已经创建好一个静态对象,调用时反应速度快。
缺点资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

2.双重检测:单例实例在第一次被使用时构建,延迟初始化,加锁synchornized。

优点资源利用率高,不执行getInstance()就不被实例,可以执行该类其他静态方法
缺点第一次加载时反应不快,由于java内存模型一些原因偶尔失败

综上所述,单例模式的注意事项有:
第一、尽量使用懒加载,资源利用率高;
第二、双重检索实现线程安全;
第三、构造方案为private;
第四、定义静态的 SingletonPattern instance对象和getInstance()方法。

基于以上思路,java参考代码如下:

package Designpatterns;

//饿汉式单例类.在类初始化时,已经自行实例化
public class SingletonPattern {
    //属性和方法
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    //私有的默认构造函数
    private SingletonPattern(){};
    //已经自行实例化
    private static final SingletonPattern single=new SingletonPattern();
    //静态工厂方法
    public static SingletonPattern getInstance(){
        return single;
    }

/*    public static void main(String[] args){
       //SingletonPattern sin1=new SingletonPattern();
        SingletonPattern sin1=SingletonPattern.getInstance();//获得单例
        SingletonPattern sin2=SingletonPattern.getInstance();//获得单例

        sin1.setName("simple");
        sin2.setName("senbao");
        System.out.println(sin1==sin2);
        System.out.println(sin1.getName());
        System.out.println(sin2.getName());
    }*/

}

package Designpatterns;


//懒汉式单例类.在第一次调用的时候实例化
public class SingletonPattern2 {
    //属性和方法
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    private SingletonPattern2(){};
    //注意,这里没有final
    private static SingletonPattern2 sin2=null;
    // public volatile static SingletonPattern2 sin2;
    public static SingletonPattern2 getInstance(){
        if(sin2==null){
            synchronized (SingletonPattern2.class){//
                if(sin2==null){//判断两次都为空,才创建
                    sin2=new SingletonPattern2();
                }
            }
        }
        return sin2;
    }

    public static void main(String[] args){
        //SingletonPattern sin1=new SingletonPattern();
        SingletonPattern sin1=SingletonPattern.getInstance();//获得单例
        SingletonPattern sin2=SingletonPattern.getInstance();//获得单例

        sin1.setName("simple");
        sin2.setName("senbao");
        System.out.println(sin1==sin2);
        System.out.println(sin1.getName());
        System.out.println(sin2.getName());
    }

}

参考:

https://mp.weixin.qq.com/s?__biz=MzI5MzYzMDAwNw==&mid=2247483950&idx=1&sn=57ead90d8305f7c8c07a8764f02d852a&scene=19#wechat_redirect
https://blog.csdn.net/wallwind/article/details/7250708
http://www.cnblogs.com/whgw/archive/2011/10/05/2199535.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值