剑指Offer 面试题2:实现Singleton模式 Java解法

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

        只能生成一个实例的类是实现了Singleton(单例)模式的类型。由于设计模式在面向对象程序设计中起着举足轻重的作用,在面试过程中很多公司都喜欢问一些与设计模式相关的问题。在常用的模式中,Singleton是唯一一个能够用短短几十行代码完整实现的模式。因此,写一个Singleton的类型是一个很常见的面试题。

        在Java中主要有6种方法能够实现单例模式。

1.饿汉模式

缺点:不管有没有调用过getSingleton(),每次都会新建一个实例。

public class Singleton{

    //一开始就新建一个实例
    private static final Singleton singleton = new Singleton();

    //默认构造方法
    private Singleton() {}

    //获得实例的方法
    public static Singleton getSingleton(){
        return singleton;
    }

}

2.懒汉模式

一开始没有新建实例,但是不能保证线程安全。

public class Singleton{

    private static Singleton singleton; //一开始没有新建实例
    private Singleton() {}
    public static Singleton getSingleton(){ //需要时再新建
        if(single == null){
            singleton = new Singleton();
        }
        return singleton;
    } 
     
}

3.线程安全的懒汉模式

能够解决懒汉模式的线程安全问题,但是效率不高。仅在懒汉模式的基础上对getSingleton()函数加上synchronized关键字修饰即可。

public class Singleton{

    private static Singleton singleton; 
    private Singleton() {}
    public static synchronized Singleton getSingleton(){ //保证线程安全
        if(single == null){
            singleton = new Singleton();
        }
        return singleton;
    } 
     
}

方法1,2,3均存在缺陷,而后面的方法4,5,6为可行的方法。

4.双重检验锁(Double Check)

解决方法3效率不高的问题

public class Singleton{

    private  volatile static Singleton singleton;
    //此处添加volatile关键字为了防止编译器自行优化代码(由于singleton = new Singleton()这句代码要做好几件事情)
 
    private Singleton() {}

    public static Singleton getSingleton(){ 
        if(singleton == null){  //第一个检验锁
            synchronized(Singleton.class){
                if(singleton == null){  //第二个检验锁
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    } 
     
}

5.静态内部类

双重检验锁的代码看起来比较复杂,静态内部类方法相对简洁。

public class Singleton{
    
    private static class SingletonHolder{
        private static final Singleton singleton = new Singleton();
    }

    private Singleton() {}

    public static Singleton getSingleton(){
        return SingletonHolder.singleton;
    }
    
}

6.枚举

枚举方法的代码最为简洁。

public enum Singleton{

    INSTANCE;
    public void whateverMethod() {}

}

//在外部通过Singleton.INSTANCE来访问实例对象

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值