标签:style blog io ar 使用 java for sp div
单例模式是很别致的一个模式,很少有人拿它跟其他模式相比,因为,单例模式很简单,很特别,作用就是保证一个类有唯一一个实例,并让一个全局变量使得它能被访问.而保证这个类只被实例化一次的办法就是把构造函数变为私有的,除了它自己都不能new新对象,然后把实例化的过程写在类自身的公有方法里,是否new新对象只有它自己判断决定,已经有了一个实例就直接返回已存在的对象,没有就new一个新实例.其他类想实例化一个对象时调这个公有方法.
//饿汉式 Class XmlConfigReader{ private static XmlConfigReader instance=new XmlConfigReader(); private XmlConfigReader(){ } public static XmlConfigReader getInstance(){ return instance; } }
//懒汉式(延迟加载lazy) Class XmlConfigReader{ private static XmlConfigReader instance =null; public static synchronized XmlConfigReader getInstance(){ if(instance==null){ instance=new XmlConfigReader(); } return instance; } }
我们常常听到"Double-Check Locking"即"双重锁定"的概念,这是因为还有一种加锁方式,即使用Lock.
Class XmlConfigReader{ private static XmlConfigReader instance; private static readonly object syncRoot=new object(); private XmlConfigReader(){ } public static XmlConfigReader getInstance(){ if(instance==null){ Lock( syncRoot) { if(instance==null){ instance=new XmlConfigReader(); } } } return instance; } }
对比:
单例模式分两类,这种静态初始化的方式是在类被加载时实例化,与懒汉式的第一次被引用时才实例化相比提前占用系统资源;但懒汉式需要加锁保证多线程访问的安全性,饿汉式却不需要.我们只好择其善者而用之…
项目中的单例应用:
DRP中几乎每个模块都有Manager,在系统开发的初期,因为只有ClientManager,使用单例模式如下:
public class ClientManager { private static ClientManager instance=new ClientManager(); private ClientManager(){} public static ClientManager getInstance(){ return instance; } }
public class BeanFactory { private static BeanFactory instance=new BeanFactory(); private final String beansConfigFile="beans-config.xml"; private Document doc; private BeanFactory(){ try { doc=new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile)); } catch (DocumentException e) { e.printStackTrace(); throw new RuntimeException(); } } public static BeanFactory getInstance(){ return instance; } }
//保存Service相关对象 private Map serviceMap=new HashMap(); /** * 根据产品编号取得service系列产品 * @param beanId * @return */ public synchronized Object getServiceObject(Class c){ //如果存在相关对象实例,返回 if(serviceMap.containsKey(c.getName())){ return serviceMap.get(c.getName()); } Element beanElt=(Element)doc.selectSingleNode("//service[@id=\"" + c.getName() +"\"]"); String className=beanElt.attributeValue("class"); Object service=null; try { service=Class.forName(className).newInstance(); //将创建好的对象放到map中 serviceMap.put(c.getName(), service); } catch (Exception e) { throw new RuntimeException(); } return service; }
通过以上分析和应用,再看单例模式的重点:
实现上,私有静态成员变量/私有构造方法/公共的静态方法;解决了全局访问和实例化控制的问题.
单例的意义不在于创建,而在于访问,也就是说,要访问或调用的对象如果不存在就创建一个,这是唯一一个,之后不能再创建;如果存在就返回该对象,尽管该对象的属性因为被重新赋值改变过无数次,对象是唯一的但不是一成不变的.
标签:style blog io ar 使用 java for sp div
原文地址:http://blog.csdn.net/zhuanzhe117/article/details/40594593