单例模式(singleton design pattern)也是常用的设计模式之一,使用单例模式就是要保证某个类在整个应用中只有一个实例存在,而且就在其本类中实例化。这样在应用中就不会同时出现某个类的多个实例,就保证了资源的合理利用。
单例模式看上去虽然简单,却也分好几中,下面就详细看看各种单例模式的区别所在:
------预先加载法------------------------------------------------------------
这种实现方式是单例模式的最简单的一种,把构造函数写成私有的(private),这样就不能再其他的类里实例化该类,然后在类中提供一个静态的实例
public class SingletonTest(){
//静态的实例
private static final SingletonTest testInstance =new SingletonTest ();
//一个私有的构造器
private SingleTest(){
}
//通过调用此方法来得到SingletonTest 类的实例
public static SingletonClass getSingletonInstance(){
return testInstance;
}
}
可思考一下这种简单的方法,我们本想让外面调用了getSingletonInstance()此方法才会创建一个实例,其实不论怎样,就算我们没有调用getSingletonInstance()这个方法,SingletonTest的实例任然会被创建,这样就会造成资源浪费。
--------延迟加载法---------------------------------------------------------------
使用延迟加载的方式就能解决上面的问题,它会保证只有外界在调用getSingletonInstance()才方法时才创建一个实例,请看
public class SingletonTest(){
private static SingletonTest testInstance = null;
private SingleTest(){
} public static SingletonTest getSingletonInstance(){
if(testInstance == null){
testInstance = new SingletonTest();
}
return testInstance;
}
} 区别: 静态实例变量 testInstance 初始化为null 获取实例的方法getSingletonInstance()中,要先判断testInstance 是否为空,如果为空(第一次的时候)才new一个SingletonTest实例,而第二次再调用的时候,因为testInstance 是static的,所以,此时就不为null了,直接返回该实例 --------多线程的情况(同步)--------------------------------------------------------------- 第二种(延迟加载)单例模式的实现,在单线程的情况下是没有什么问题,如果是多线程的情况下就有问题了,所以就要加锁,如下 public class SingletonTest{ private static SingletonTest testInstance = null; private SingletonTest(){ } //给获取实例的方法加上【同步锁】 public synchronized static SingletonTest getSingletonInstance(){ if(testInstance == null){ testInstance = new SingletonTest(); } return testInstance; } } 给getSingletonInstance()方法加上同步锁以后,如果有多个线程,那么其他线程必须等前面的线程创建完成后才能调用此方法 --------解决加了synchronized 以后,性能慢的问题------------------------------------ 因为加了synchronized修饰的同步块可是要比一般的代码段慢上几倍的,如果怎的有很多线程,那么就会调用多次 getSingletonInstance()方法,那就要马上考虑这个所引起的性能问题了,【因为第三种 是 在整个方法上都加了锁,而实际上呢,我们加锁的真正原因就是在检查testInstance 是否为null的操作】 public class SingletonTest{ private static SingletonTest testInstance = null; private SingletonTest(){ } public static SingletonTest getSingletonInstance(){ if(testInstance == null){ //只有当testInstance真的为null的时候才给后面的判断的那块加上【同步锁】,这样性能上才会得到优化 synchronized (SingletonTest.class){ if(testInstance == null){ testInstance = new SingletonTest(); } } } return testInstance; } } 注意:一定不能把同步锁把判断testInstance 为null加锁 |
|