单例模式是非常别致的一个模式,非常少有人拿它跟其它模式相比,由于,单例模式非常easy,非常特别,作用就是保证一个类有唯一一个实例,并让一个全局变量使得它能被訪问.而保证这个类仅仅被实例化一次的办法就是把构造函数变为私有的,除了它自己都不能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;
}
}

随着系统复杂度的添加,出现越来越多的Manager,如ItemManager,FlowCardManager等,并且这时候Manager与Dao进行了分离,出现了分层.系统採用了抽象工厂+反射技术实现Manager类和Dao类的实例化.单例又被应用在工厂中.

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;
}
}

下面这段代码是工厂类中得到Manager的单例实现的一部分.開始还真以为是享元模式,后来发现这个实现比享元模式还要灵活.它能保证对象唯独一个实例,因此还是单例模式的应用.越到后面用到的东西越多,已经不只局限于某一个模式或技术了,享元,单例,工厂,代理……

//保存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;
}

通过以上分析和应用,再看单例模式的重点:

实现上,私有静态成员变量/私有构造方法/公共的静态方法;攻克了全局訪问和实例化控制的问题.

单例的意义不在于创建,而在于訪问,也就是说,要訪问或调用的对象假设不存在就创建一个,这是唯一一个,之后不能再创建;假设存在就返回该对象,虽然该对象的属性由于被又一次赋值改变过无数次,对象是唯一的但不是一成不变的.

Java项目(5)——单例模式的应用与研究的更多相关文章

  1. java项目(学习和研究)

    java项目就是研究,不断的对项目进行迭代,把产品做的越来越好,就是research. 自己想着做一个java项目把,可以类似牛客网,想好自己的预期产品,在设计的过程中可以不断改进和扩展,在做这个项目 ...

  2. JAVA 项目中使用 H2 数据库

    为什么要使用H2数据库 H2数据库是可以嵌入到JAVA项目中的,因为只需要导入一个jar包即可,所以非常的方便. 项目中导入H2 将H2的jar包放到classpath里即可,我是用的maven,ma ...

  3. Android 如何在Eclipse 引入外部纯Java项目(不是打成Jar使用)

    应用情景--如标题: 在Eclipse的 “Android启动项目”中引入“外部的纯Java项目”,能运行的只有是基于Android的测试代码才可以. 一直很纳闷,如果外部写好一个Java插件(例如服 ...

  4. java项目中.classpath,.settings,.project,mymetadata文件的作用

    今天犯了一个错误,误修改了本地的.classpath文件,导致项目好多地方报错,之前也没有仔细的研究过项目中的一些生成文件的作用. 今天特此进行记录. 不管我们在eclipse中新建任何的Java项目 ...

  5. Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境(图文详解)

    这篇博客 是在Scala IDEA for Eclipse里手动创建scala代码编写环境. Scala IDE for Eclipse的下载.安装和WordCount的初步使用(本地模式和集群模式) ...

  6. 关于JAVA项目报表选型过程

    本人一直在走.NET技术路线,考虑到后期公司搞JAVA项目,也算是进行技术灾备,开始对JAVA技术进行关注.万事开头难,也是上来一头包.没办法,顶着上吧.上面开始分给我任务了.就是对后期项目报表进行方 ...

  7. 利用内存分析工具(Memory Analyzer Tool,MAT)分析java项目内存泄露

    转载:http://blog.csdn.net/wanghuiqi2008/article/details/50724676 一.开发环境: 操作系统:ubuntu 14.04 IDE:Eclipse ...

  8. Linux上Makefile管理java项目

    前面文章讲到了Linux上通过.spec文件与rpmbuild命令将java程序打包为RPM安装包, 现阶段遇到新的需求: 使用Makefile来操纵java的编译.打包 该需求以前面的内容为基础 可 ...

  9. maven构建java项目、web项目

    maven构建java项目.web项目 一.mvn构建web项目 1安装mvn(包括path) 2命令:mvn archetype:create -DgroupId=cn.edu.sdau.neat ...

随机推荐

  1. IE下target获得焦点时存在虚线的问题

    IE下target获得焦点时存在虚线时,用IE的特定属性:hidefocus="true"即可解决!

  2. js 动画性能分析 transfrom

    1.动画实现代码 (1)使用定位实现: <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...

  3. 〖Linux〗gvim使用alt+1,2,3..进行标签页切换

    gvim ~/.gvimrc,往里边添加: """"""""""""" ...

  4. import 如何工作

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #import 如何工作 #程序第一次导入指定文件时,会执行三个步骤 #1)找到模块文件 #2)编译成位码(需 ...

  5. PHP开发安全问题

    1.不相信表单 对于一般的Javascript前台验证,由于无法得知用户的行为,例如关闭了浏览器的javascript引擎,这样通过POST恶意数据到服务器.需要在服务器端进行验证,对每个php脚本验 ...

  6. servlet 转发和超链接转发

    超链接属于客户端跳转,request是无法取得属性的 我们知道一个jsp相当与一个servlet 例如,客户端请求A.jsp页面,在A.jsp页面调用request.getAttribute方法放入属 ...

  7. Megcup 2017 决赛第一题 规则

    2017Megcup 2017Megcup决赛第三题题解 只做出了一道题,虽然慢慢地退出了前128名,但还是要记录一下. 10点钟开始,一看第一题很熟悉,因为研究过格点图中电流问题,其实就是求解线性方 ...

  8. 【C++】关于带const的指针问题

    区分const出现在*前还是*后 前: 例如const int *p,这种表示情况下,p本身可以改变,即p可以指向不同的地址, 但是p指向的内容不可改变. 就像你喜欢看书,图书馆规定你可以任意借阅及更 ...

  9. WCF中可以使用SVCUtil.exe生成客户端代理类和配置文件

    1.找到如下地址“C:\Windows\System32\cmd.exe”  命令行工具,右键以管理员身份运行(视系统是否为win7 而定)         2.输入如下命令: C:\>cd C ...

  10. 【jQuery】jquery-ui autocomplete智能提示

    jQuery UI,简而言之,它是一个基于jQuery的前端UI框架.我们可以使用jQuery + jQuery UI非常简单方便地制作出界面美观.功能强大.跨浏览器兼容的前端html界面. Auto ...