一天学一个模式_第三天:单例模式
概念:
顾名思义,就是只有一个实例。
作为对象的创建模式[GOF95], 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
要点:
一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。
可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。
案例:
先看两段代码(注意描述部分与注释);
1,饿汉式单例类
/**
* @author wonter
* <b>描述:</b>饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变 <br>
* <b>邮件:</b> yiyu1@163.com <br>
*/
public class Singleton {
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
private Singleton(){
//空构造 防止被其他类new
}
//外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
2,懒汉式单例类
/**
* @author wonter
* <b>比较:</b> 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次。使用时生成实例,提高了效率! <br>
*<b> 描述:</b>懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的 <br>
* <b>邮件:</b> yiyu1@163.com <br>
*/
public class Singleton {
private static Singleton instance = null;
//抽象集团类,线程互斥,排队模式
public static synchronized Singleton getInstance() {
if (instance==null)// 线程1
instance=new Singleton();
//线程1后,才允许线程2运行
return instance;
}
}
3,什么更适合于商业项目
/**
* @author wonter
*<b> 描述:</b>直接 new 一个对象传递给类的成员变量 singletonpattern,你要的时候 getInstance()直接返回给你 <br>
* <b>邮件:</b> yiyu1@163.com <br>
*/
public class SingletonPattern {
private static final SingletonPattern singletonPattern= new SingletonPattern();
//限制住不能直接产生一个实例
private SingletonPattern(){
//空构造 防止被其他类new
}
public synchronized static SingletonPattern getInstance(){
return singletonPattern;
}
}
4.项目案例代码:(片段)
/**
* <b>类描述:</b>集团代理类信息 <br>
* <b>邮件:</b> yiyu1@163.com <br>
* <b>手机:</b> 13018061144 <br>
* <b>编写日期:</b> 2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* @see java.lang.String
* @see java.lang.Integer
* @author wonter
* BlocDAO的代理类 BlocProxy <br>
* 此类不允许用户new,因为多线程时不同操作会有死锁或者乐观锁的问题 (业务方法类)
*/
public abstract class BlocProxy {
public static final String FINDALL = "select * from Bloc where Blocstate=1";
/**
* <b>编写日期:</b> 2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* <b> 描述:</b>空构造 防止被其他类new<br>
* @see com.tb.crm.dao.factory.DAOAdapter#insert(java.lang.String,
* java.lang.Object[])
* @author wonter
*/
private BlocProxy() {
}
/**
* <b>编写日期:</b> 2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* <b> 描述:</b> 抽象集团类,线程互斥,排队模式<br>
* @see com.tb.crm.dao.factory.DAOAdapter#insert(java.lang.String,
* java.lang.Object[])
* @author wonter
*/
public synchronized static BlocProxy getInstance() {
return new BlocProxy() {
};
}
/**
* <b>编写日期:</b> 2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* <b>最近修改日期:</b>2011-3-24 <br>
* 业务方法 :查询Bloc表全部信息 findAll
* @see com.tb.crm.dao.factory.DAOAdapter#insert(java.lang.String,
* java.lang.Object[])
* @return List
* @author wonter
*/
public List findAll(){
List list=null;
try {
if(list==null)// 线程1
list = DAOFactory.getInstance(BlocDAO.class).findAll(
FINDALL, Bloc.class);// 如果线程2,线程1后允许。
return list;
} catch (Exception e){
e.printStackTrace();
}
return null;
}
好处:
单例模式属于构建模式之一,实例控制--伸缩性
缺点:
系统开销---开发混淆---对象生命周期
/**
* @author wonter
* <b>描述:</b> 一天学一个模式 更新中,请关注我的微博! <br>
* <b>微博:</b>http://weibo.com/wontter<br>
* <b>邮件:</b> yiyu1@163.com <br>
*/
加微信:wonter 发送:技术Q
医疗微信群:
加微信:wonter 发送:医疗Q
更多文章关注公众号: