单例模式1
2016-07-05 17:01
288 查看
Java中单例模式定义:
一个类有且仅有一个实例,并且自行实例化向整个系统提供。
使用前提:
在一个系统中要求只有一个类的实例时应当使用单例模式。
要点:
一是单例模式的类只提供私有的构造函数,
二是类定义中含有一个该类的静态私有对象,
三是该类提供了一个静态的共有的函数用于创建或获取它本身的静态私有对象。
其中静态的好处:如果每次对象请求引用时都要检查是否存在类的实例,就需要一些开销。可以通过使用静态初始化解决此问题。
好处:一个对象节约内存。缺点:效率低。
模式一恶汉模式:类加载时就初始化。
public class EagerSingleton {
//静态私有对象
private static final EagerSingleton singleTon=new EagerSingleton();
//私有的默认构造方法,此类不能被继承
private EagerSingleton(){}
//静态公共的工厂方法
public static EagerSingleton getInstance(){
return singleTon;
}
}
模式二懒汉模式:第一次调用才会初始化。
public class LazySingleton {
private static LazySingleton singleton=null;
//私有的默认构造方法,此类不能被继承
private LazySingleton(){}
//同步,静态工厂方法,返回此类的唯一实例
public synchronized static LazySingleton getInstance(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}
模式三登录模式:克服饿汉式单例类和懒汉式单例类不可继承的缺点而设计的。
父类代码:
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);
}
}
子类代码:
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");
}
}
一个类有且仅有一个实例,并且自行实例化向整个系统提供。
使用前提:
在一个系统中要求只有一个类的实例时应当使用单例模式。
要点:
一是单例模式的类只提供私有的构造函数,
二是类定义中含有一个该类的静态私有对象,
三是该类提供了一个静态的共有的函数用于创建或获取它本身的静态私有对象。
其中静态的好处:如果每次对象请求引用时都要检查是否存在类的实例,就需要一些开销。可以通过使用静态初始化解决此问题。
好处:一个对象节约内存。缺点:效率低。
模式一恶汉模式:类加载时就初始化。
public class EagerSingleton {
//静态私有对象
private static final EagerSingleton singleTon=new EagerSingleton();
//私有的默认构造方法,此类不能被继承
private EagerSingleton(){}
//静态公共的工厂方法
public static EagerSingleton getInstance(){
return singleTon;
}
}
模式二懒汉模式:第一次调用才会初始化。
public class LazySingleton {
private static LazySingleton singleton=null;
//私有的默认构造方法,此类不能被继承
private LazySingleton(){}
//同步,静态工厂方法,返回此类的唯一实例
public synchronized static LazySingleton getInstance(){
if(singleton==null){
singleton=new LazySingleton();
}
return singleton;
}
模式三登录模式:克服饿汉式单例类和懒汉式单例类不可继承的缺点而设计的。
父类代码:
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);
}
}
子类代码:
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");
}
}
相关文章推荐
- spring3.0以后移除ContextLoaderServlet,使用ContextLoaderListener获取ApplicationContext
- 团体程序设计天梯赛-练习集 L2-005. 集合相似度
- EF分组查询与视图显示
- HDOJ/HDU 1241 Oil Deposits(经典DFS)
- [Learning OpenCV入门 3]OpenCV的图像变换
- oracle数据库报死锁异常
- QString 转double,double转QString 中的小数点问题
- Laravel 设置时区
- SQLite常用SQL语句
- HDOJ/HDU 1241 Oil Deposits(经典DFS)
- java修改图片大小
- 去重 oracle
- 智力趣题--多少个三角形
- 如何更改Linux中默认的openjdk为自己安装的JDK
- L2-008. 最长对称子串
- java 获取路径的各种方法
- 17.2节练习
- Golang-web网站入门-服务器入门
- HDU-4609-3-idiots
- 网络加载图片并实现本地缓存与获取