《剑指offer》面试题2 实现Singleton模式--用JAVA实现

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

要生成单例模式,有以下几种实现方式:

方法一:懒汉式(只适用于单线程)

要只能创建一个单例,需要把构造函数设为私有函数,并且创建一个私有静态实例,只有当该实例为null时,才能创建。

只有在需要的时候才会创建。

public class Singleton1{

    private Singleton{

    }

    private static Singleton1 instance=null;

    public static Singleton getInstance(){

        if(instance==null){

            instance=new Singleton1();

        }

        return instance;

    } 

}

缺点:当在多线程情况下,如果有两个线程同时运行到判断instance是否为空时,instance没有被创建,那么两个线程都会创建一个实例,此时不再满足单例模式要求。

方式二:饿汉式(可以在多线程环境下工作,但效率不高)

public class EagerSingleton {
	private static EagerSingleton instance=new EagerSingleton();
	private EagerSingleton(){}
	public static synchronized EagerSingleton getInstance() {
		return instance;
	}

}

缺点:在两个线程想同时创建一个实例时,一个线程得到同步锁,另一个线程只能等待。第一个线程完成之后,第二个线程进行加锁,他发现实例已被创建,则不会重复创建。加锁是一个非常耗时的操作,在没有必要的时候需要避免。

方式三:使用同步关键字双重加锁

public class DoubleLockSingleton {
	private static volatile DoubleLockSingleton instance;//volatile关键字是必须的,用以确保多线程共享实例
	private DoubleLockSingleton(){}
	public static DoubleLockSingleton getInstance(){
		if(instance==null){
			synchronized(DoubleLockSingleton.class){
				if(instance==null){
					instance=new DoubleLockSingleton();
				}
			}
		}
		return instance;
	}
	
}

当instance没有被创建时,加锁,反之不加锁,只有在第一次创建时instance为null,所以只有在第一次创建实例时需要加锁,减少了不必要的时间消耗。

缺点:用两个if判断,代码实现复杂,容易出错。

方法四:实现按需创建实例

public class SingletonBest {
	private SingletonBest(){}
	/**
	 *  类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 
     *  没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。 
	 * @author DELL
	 *
	 */
	public static class Singleton{
		private static SingletonBest instance=new SingletonBest();
	}
	/**
	 * 静态初始化器,由JVM来保证线程安全
	 * @return
	 */
	public static SingletonBest getInstance(){
		return Singleton.instance;
	}
}

该方法使用了静态成员内部类,只有在调用Singleton.instance时才会被创建,实现了按需创建的要求。

方法五:单元素枚举

public enum EnumSingleton {
	//定义一个枚举的元素,它就代表了Singleton的一个实例。
	instance;
	public void singletonOperation(){
		//功能处理
	}
}

通过这几种方式实现单例模式的创建,不仅让我学到了单例模式的思想,更加学到了要实现一个优秀的算法,还需思考更多。编程更多的是要有一种思想,以后还要多刷题,达到思想更加符合一个程序员。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值