单例模式
2016-07-14 17:16
344 查看
synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。public class Singleton {
//定义一个私有的静态全局变量来保存该类的唯一实例
private static Singleton singleton;
//私有的构造函数
private Singleton() {}
//全局访问点
public static Singleton GetInstance() {
//这里可以保证只实例化一次 ,即在第一次调用时实例化 ,以后调用便不会再实例化
//双重检查锁定。第一重 singleton == null
if (singleton == null) {
sychronized(Singleton.class) {
//第二重 singleton == null
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}一、单例模式是用来实现在整个程序中只有一个实例的。
二、单例类的构造函数必须为私有,同时单例类必须提供一个全局访问点。
三、在ssh2 项目中 , struts2的action交由spring管理的时候 ,spring默认是singleton的 ,而struts2的action显然是有状态的 ,所以必须显示设置为 scope=“prototype”,prototype为原型模式 , 每次action请求过来都会创建一个action、但是对那些Dao的实现类推荐scope=“singleton” ,因为这些类没有状态,用singleton只需维护一个实例,显然性能高一些
四、单例模式的实现方式推荐以下方法:【静态内部类】
* 内部类只在需要的时候才会被类加载器加载,实现了懒加载,即在需要的时候才实例化出一个Manager,而且是唯一的一个,同时由于instance是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性(即使在高并发的情况下多个线程同时访问getInstance()方法 也能够保证实例的唯一性),静态内部类实现单例是最简单最安全的一种解决方案
//定义一个私有的静态全局变量来保存该类的唯一实例
private static Singleton singleton;
//私有的构造函数
private Singleton() {}
//全局访问点
public static Singleton GetInstance() {
//这里可以保证只实例化一次 ,即在第一次调用时实例化 ,以后调用便不会再实例化
//双重检查锁定。第一重 singleton == null
if (singleton == null) {
sychronized(Singleton.class) {
//第二重 singleton == null
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}一、单例模式是用来实现在整个程序中只有一个实例的。
二、单例类的构造函数必须为私有,同时单例类必须提供一个全局访问点。
三、在ssh2 项目中 , struts2的action交由spring管理的时候 ,spring默认是singleton的 ,而struts2的action显然是有状态的 ,所以必须显示设置为 scope=“prototype”,prototype为原型模式 , 每次action请求过来都会创建一个action、但是对那些Dao的实现类推荐scope=“singleton” ,因为这些类没有状态,用singleton只需维护一个实例,显然性能高一些
四、单例模式的实现方式推荐以下方法:【静态内部类】
public class Manager { private Manager() {} public static Manager getInstance() { return ManagerHolder.instance; } private static class ManagerHolder { private static final Manager instance = new Manager(); } }再来一例
public class JobQueue<T> { private LoanTask task; private static class LazyHolder { // 用户相关队列 private static final JobQueue <ValueEvent> USER_INSTANCE = new JobQueue<ValueEvent>(new UserTask()); } /** * 用户相关处理:注册开户,绑定银行卡等 * @return */ public static JobQueue <ValueEvent> getUserInstance() { return LazyHolder.USER_INSTANCE; } private JobQueue(LoanTask task){ super(); this.task = task; } }然后解释下为什么要用这种方式:
* 内部类只在需要的时候才会被类加载器加载,实现了懒加载,即在需要的时候才实例化出一个Manager,而且是唯一的一个,同时由于instance是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性(即使在高并发的情况下多个线程同时访问getInstance()方法 也能够保证实例的唯一性),静态内部类实现单例是最简单最安全的一种解决方案
相关文章推荐
- ORIGIN 9.0 拟合曲线延伸
- 集合转换为Json数组
- HTML5笔记二:历史管理history
- UESTC - 149 解救小Q
- 【腾讯优测干货分享】Android5.0-6.0双卡适配指南
- jquery移动元素位置
- JS-正则表达式4
- 点击按扭后显示DIV,当然这个DIV 就显示在按扭旁边,当鼠标移动到DIV上时无变化,当鼠标移出DIV的时候,让DIV隐藏
- js轮播图代码分享
- 香蕉派 banana pi BPI-M64 四核心64位开源单板计算机 全志A64方案
- C# 线程同步
- 我们添加了两个短裤!
- 直方图均衡化
- Android开发,关于Canvas的使用,绘图的各种用法
- mongodb 数组内容匹配删除方法, $all 用法
- 转学习笔记:Caffe上配置和运行MNIST
- 卷积神经网络
- The type java.lang.Object cannot be resolved.
- 自动开启snmp服务
- apache commons fileupload svn仓库(2016-07-01更新)