浅析设计模式–(一)单例模式
单例模式:在实际编程中往往遇到,某个类只需要拥有一个对象就可以满足生产的情况。在这时使用单例模式可以很好的避免多余的对象产生,重复的对象产生,并且满足现实中只有一个总统一个校长的这种实际。使用单例模式,可以方便的节约内存空间,减少创建对象的开销,提高程序效率,并且利于维护,多处公用一个对象只需要维护一个对象即可。共享对象必然带来线程的安全问题,但是只要合理的处理就可以达到高效。以下介绍几种单例模式的实现方式:
- 恶汉模式的单例
package com.test.singletion;
public class Singletion {
//私有的构造方法--为了防止外部创建对象。
private Singletion(){
}
//不能再外部创建对象,那么就在它的内部维护一个对象。这里采用恶汉模式,类在初始化的时候就生成一个对象。
//这个对象 用static 修饰,属于类的,内存中存放于 方法区。
private static Singletion singletion = new Singletion();
//提供对外的静态方法,供使用者调用。
public static Singletion getInstance(){
return singletion;
}
}
// 这种类型单例的优点是:简单,可靠, 缺点是 在类的加载期间就会创建对象,对于一些需要进行较多初始化的类或者是不常用的类不建 // 议使用这种单例的写法,因为会延长服务器启动的时间,有可能浪费资源
//因此我们就需要下面的这种单例模式了,懒加载的写法。
- 懒汉模式的单例
package com.test.singletion;
/**
懒汉模式的单例
@author liuds1
懒汉模式的 单例写法,确保系统没有额外的负担,啥时候使用啥时候创建,但是要考虑多线程的情况。
*/
public class LazySingletion {
private static LazySingletion lazySingletion = null;
private LazySingletion(){
System.out.println("I am a LazySingletion ");
}
public synchronized static LazySingletion getInstance(){
System.out.println("now you get a LazySingletion Instance");
if(lazySingletion==null){
return new LazySingletion();
}
return lazySingletion;
}
//其他的方法
public void othermethod(){
System.out.println("I am a otherMethod ");
}
//其他的属性
private String name ;
}
// 延迟加载引入了 同步锁,synchronized 实现的是悲观锁。性能较低,每次生成的单例的时候都要进行加锁判断,在高并发的情况
//下,执行效率较低,那么有没有一种 即是懒加载 又能高效的产出单例呢?
- 使用内部类创建单例
package com.test.singletion;
/**
内部类实现的单例
@author liuds1
*/
public class InnerClassSingletion {
private static class InnerClass {
private static InnerClassSingletion innerClassSingletion = new InnerClassSingletion();
}
private InnerClassSingletion(){
}
public static InnerClassSingletion getInstance(){
//只有在执行这一句代码的时候才会进行初始化 内部类 ,在 InnerClassSingletion 被加载的时候不会初始化他的内部类 InnerClass。
return InnerClass.innerClassSingletion;
}
}
- 列表内容
在以上介绍的 三种单例的写法,指的是程序中实现的单例,在web项目中,这样的单例作用范围是在整个应用。在实际项目中,我们还会用到spring 管理的单例。有些情况写我们会简单的把一个类 交给spring 管理,spring 默认管理的bean 都是单例的。
这样的话这个类是在spring容器中生效。若一个类的对象仅仅需要在spring 容器中 保证单例即可,那么可以使用spring管理该类实现单例。
package com.test.singletion;
/**
* 一个spring 管理的类
* @author liuds1
*
*/
public class SpringSingletion {
public SpringSingletion(){
}
public void dosomething(){
}
}
配置文件
<bean id="springSingletion " class="com.test.singletion.SpringSingletion " ></bean>
spring管理的类,并不是真正的单例,我们他的类并不一定有私有的构造方法,并且我们在使用的时候,使用声明的
bean 才是单例的。我们仍然可以通过new 来创建其他对象。
另外单例并不是绝对的,反射可以破坏单例。