java设计模式 单例
2016-04-05 16:34
507 查看
一、单例模式要点
1.单例,顾名思义,某个类只能有一个实例。
2.它必须自行创建这个唯一的实例。
3.它必须自行向整个系统提供这个实例。
二、单例模式的三种实现
1.饿汉式单例类(类加载时就初始化)
Java代码
public class EagerSingleton {
//私有的类成员常量
private static final EagerSingleton SINGLETON=new EagerSingleton();
//私有的默认构造方法,此类不能被继承
private EagerSingleton(){}
//静态工厂方法
public static EagerSingleton getInstance(){
return SINGLETON;
}
}
Java语言中的单例类的一个最重要的特点是类的构造方法是私有的,从而避免外界利用构造方法直接创建出人意多飞实例。
2.懒汉式单例类(第一次调用才初始化,延迟)
Java代码
public class LazySingleton {
private static LazySingleton singleton=null;
//私有的默认构造方法,此类不能被继承
private LazySingleton(){}
//同步,静态工厂方法,返回此类的唯一实例
public synchronized static LazySingleton getInstance(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}
对2的懒汉式的另外一种改进
Java代码
public class DoubleCheckSingleton {
private volatile static DoubleCheckSingleton singleton = null;
// 私有的默认构造方法,此类不能被继承
private DoubleCheckSingleton() {
}
// 静态工厂方法,返回此类的唯一实例
public static DoubleCheckSingleton getInstance() {
if (singleton == null) {
synchronized (DoubleCheckSingleton.class) {
if (singleton == null) {
singleton = new DoubleCheckSingleton();
}
}
}
return singleton;
}
}
3.登记式单例类
登记式单例类是为了克服饿汉式单例类和懒汉式单例类不可继承的缺点而设计的。
Java代码
package com.zzs.singleton;
import java.util.HashMap;
public class RegSingleton {
private static HashMap registry=new HashMap();
/**静态代码块
*静态代码块优先于主方法执行,而在类中定义的静态代码会优先于构造块执行,而且不管产生多少对象,静态代码块只执行一次。
*/
static{
RegSingleton singleton=new RegSingleton();
registry.put(singleton.getClass().getName(), singleton);
}
protected RegSingleton(){}
public static RegSingleton getInstance(String name){
if(name==null){
name="com.zzs.singleton.RegSingleton";
}
if(registry.get(name)==null){
try {
registry.put(name, Class.forName(name).newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return (RegSingleton) registry.get(name);
}
}
Java代码
package com.zzs.singleton;
public class RegSingletonChild extends RegSingleton {
//由于子类必须允许父类以构造方法调用产生实例,所以它的构造方法必须是公开的,protected或public
protected RegSingletonChild() {
}
//静态方法工厂
public static RegSingletonChild getInstance() {
return (RegSingletonChild) RegSingleton
.getInstance("com.zzs.singleton.RegSingletonChild");
}
}
三、在什么情况下使用单例模式
使用单例模式的一个必要条件:在一个系统中要求只有一个类的实例时应当使用单例模式。反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例类。java语言中的Runtime对象就是一个单例模式。
1.单例,顾名思义,某个类只能有一个实例。
2.它必须自行创建这个唯一的实例。
3.它必须自行向整个系统提供这个实例。
二、单例模式的三种实现
1.饿汉式单例类(类加载时就初始化)
Java代码
public class EagerSingleton {
//私有的类成员常量
private static final EagerSingleton SINGLETON=new EagerSingleton();
//私有的默认构造方法,此类不能被继承
private EagerSingleton(){}
//静态工厂方法
public static EagerSingleton getInstance(){
return SINGLETON;
}
}
Java语言中的单例类的一个最重要的特点是类的构造方法是私有的,从而避免外界利用构造方法直接创建出人意多飞实例。
2.懒汉式单例类(第一次调用才初始化,延迟)
Java代码
public class LazySingleton {
private static LazySingleton singleton=null;
//私有的默认构造方法,此类不能被继承
private LazySingleton(){}
//同步,静态工厂方法,返回此类的唯一实例
public synchronized static LazySingleton getInstance(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}
对2的懒汉式的另外一种改进
Java代码
public class DoubleCheckSingleton {
private volatile static DoubleCheckSingleton singleton = null;
// 私有的默认构造方法,此类不能被继承
private DoubleCheckSingleton() {
}
// 静态工厂方法,返回此类的唯一实例
public static DoubleCheckSingleton getInstance() {
if (singleton == null) {
synchronized (DoubleCheckSingleton.class) {
if (singleton == null) {
singleton = new DoubleCheckSingleton();
}
}
}
return singleton;
}
}
3.登记式单例类
登记式单例类是为了克服饿汉式单例类和懒汉式单例类不可继承的缺点而设计的。
Java代码
package com.zzs.singleton;
import java.util.HashMap;
public class RegSingleton {
private static HashMap registry=new HashMap();
/**静态代码块
*静态代码块优先于主方法执行,而在类中定义的静态代码会优先于构造块执行,而且不管产生多少对象,静态代码块只执行一次。
*/
static{
RegSingleton singleton=new RegSingleton();
registry.put(singleton.getClass().getName(), singleton);
}
protected RegSingleton(){}
public static RegSingleton getInstance(String name){
if(name==null){
name="com.zzs.singleton.RegSingleton";
}
if(registry.get(name)==null){
try {
registry.put(name, Class.forName(name).newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return (RegSingleton) registry.get(name);
}
}
Java代码
package com.zzs.singleton;
public class RegSingletonChild extends RegSingleton {
//由于子类必须允许父类以构造方法调用产生实例,所以它的构造方法必须是公开的,protected或public
protected RegSingletonChild() {
}
//静态方法工厂
public static RegSingletonChild getInstance() {
return (RegSingletonChild) RegSingleton
.getInstance("com.zzs.singleton.RegSingletonChild");
}
}
三、在什么情况下使用单例模式
使用单例模式的一个必要条件:在一个系统中要求只有一个类的实例时应当使用单例模式。反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例类。java语言中的Runtime对象就是一个单例模式。
相关文章推荐
- (Eclipse打包问题)Export aborted because fatal lint errors we
- java中HashMap简单使用
- spring cache
- spring事务管理
- java的反射机制浅谈
- JCR集成Java内容仓库和Spring
- Java泛型(1)
- java-多线程-join函数
- JAVA 封神之路
- java 读取文件路径空格和中文的处理
- java8中map的新方法--replace
- JAVA安全控制框架 —— Shiro
- Spring MVC 配置多数据源
- Java堆栈存储数据类型
- HashMap 源码解析
- Java多线程之ExecutorService
- Java并发编程系列之十八:读写锁
- Java HotSpot VM Options
- Eclipse 自动提示设置
- java的下拉框选择