java设计模式——单例模式

在Java设计模式中,单例模式无疑是使用特别频繁的一种,本文就介绍一下单利模式的常用形式

单例模式主要分为饿汉式和懒汉式,作用是保证这个类只会被实例化一个对象。饿汉式是在穿件对象引用的时候就实例化对象,懒汉式用于延迟加载,将会在需要使用此对象时实例化对象,懒汉式往往会带来一些安全性问题。下面就详细描述一下两种单利模式。


饿汉式单例模式(例):

public class SingleInstance{

	//创建并实例化一个私有的静态对象,private保证不会被外界直接调用,static保证只会被创建一个对象
	private static SingleInstance singleInstance = new SingleInstance();

	//私有化构造器,作用是不让外界使用构造方法来实例化对象,而是只能通过SingleInstance提供的共有方法来获取
	private SingletonInstance(){  
        
    }  
      
    //提供一个公有方法,外界通过此方法获取到这个类的对象
    public static SingletonInstance getInstance(){  
        return singleInstance;  
    }  

}

饿汉式比较简单,就不再赘述,重点看注释


懒汉式将从不安全到安全由浅入深讲解,先看最简单的写法:

public class SingleInstance{
	private SingleInstance(){}
	
	private static SingleInstance singleInstance;

	public static SingleInstnce getSingleIntance(){
	
		singleInstance = new SingleInstance();
		return singleInstance;
	}
}
从代码中可以看到,外界如果调用了getInstance()方法就会去实例化一个singleInstance方法,这样不能满足只允许实例化一个对象的需求,所以我们加上一个判断,如果singleInstance对象为null就实例化,否则就直接返回,如以下代码
public class SingleInstance{
	private SingleInstance(){}
	
	private static SingleInstance singleInstance;

	public static SingleInstnce getSingleIntance(){
		if(singleInstance == null){
			
			singleInstance = new SingleInstance();
		}
		return singleInstance;
	} 
}

现在我们考虑另外一个问题,假如现在有连个线程,线程A和线程B,当线程A执行完判断,并且判断结果为空,但是还没有执行singleInstance = new SingleInstance()语句时,线程B获得了CPU资源,线程B也做了判断,由于线程A没有实例化对象,所以线程B继续执行,实例化了一个singleInstance对象,此时就有了一个singleIntance对象,然后线程A有获得了CPU资源,继续执行,由于线程A在之前已经执行过if语句,所以此时不在执行,依然认为singleInstance为空,所以也继续执行,实例化了一个singleInstance对象,此时就有了两个singleIntance对象,也不能满足只能实例化一个对象的需求,所以需要再次修改。

现在我们来加上同步锁就可以解决这个问题了

public class SingleInstance{
	private SingleInstance(){}

	private static SingleInstance singleInstance;

	public static SingleInstnce getSingleIntance(){
		synchonized(SingleInstance.class){
			if(singleInstance == null){
				singleInstance = new SingleInstance();
			}
		}
		return singleInstance;
	}
}

这样就解决线程安全问题了,但是新的问题产生了,每次调用getSingleInstance()方法是都需要去判断同步锁,这样太浪费资源,所以仍然需要改进,我们给他加上双重判断,如果是空就执行同步锁判断,否则就不去执行了
public class SingleInstance{
	private SingleInstance(){}

	private static SingleInstance singleInstance;

	public static SingleInstnce getSingleIntance(){
		if(singleInstance == null){
			synchonized(SingleInstance.class){
				if(singleInstance == null){
					singleInstance = new SingleInstance();
				}
			}
		}
		return singleInstance;
	}
}

到此就完美解决了线程安全的问题,这是一种懒汉式的写法,另外一种是使用内部类来实现,先看代码

public class SingleInstance{
	private SingleInstance(){}
	private static class InnerClass
	{
		private static SingleInstance singleInstance = new SingleInstance();
	}

	public SingleInstance getSingleInstance(){
		return SingleInstance.InnerClass.singleInstance;
	}
}


可以看到我们在SingleInstance中添加了一个私有静态内部类InnerClass,在InnerClass中实例化了一个对象。然后在SingleInstance提供的共有方法中来返回了这个对象



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值