您的位置:首页 > 其它

单例模式

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只需维护一个实例,显然性能高一些
四、单例模式的实现方式推荐以下方法:【静态内部类】
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()方法 也能够保证实例的唯一性),静态内部类实现单例是最简单最安全的一种解决方案
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: