单例模式是非常别致的一个模式,非常少有人拿它跟其它模式相比,由于,单例模式非常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. UDP和TCP的比較

    当client须要请求数据库server上的某些数据时,它至少须要三个数据报来建立TCP连接.三个数据报礼发送和确认少量数据,三个用来关闭连接. 然而,假设使用UDP的话,只须要发出两个数据报就能达到 ...

  2. vue 开发中的常见问题

    (一)eslint静态检查 在大家用vue-cli创建工程的时候,会有一项,使用使用eslint,如果选择了y,那么工程就会安装并启用eslint. 这里列举一下常见的错误: 1.多余的分号 2.定义 ...

  3. Stage3d AGAL GPU处理照片 旧照片效果 sepia || pixelbender

    如果看不到下边的flash,请更新flash player到最新版本. 利用AGAL实现旧照片效果,大家可以对照一下之前一篇文章,关于图像处理(pixelbender).硬件处理肯定会更快,但这里无法 ...

  4. struts2接收参数的几种形式

    1.使用属性 HTML: <form action="login" method="post" name="form1"> 用户 ...

  5. 身份证查询API

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #http://apistore.baidu.com/apiworks/servicedetail/113.h ...

  6. 兼顾pc和移动端的textarea字数监控的实现方法

    概述 pc端移动端中文本框监控字数的功能的一种较为简单的实现,考虑到安卓和IOS输入法输入过程中是否触发keyup的差异.利用监听compositionstart判断是否开启了输入法.从而实现体验较为 ...

  7. [Spring MVC] - JSP + Freemarker视图解释器整合(转)

    Spring MVC中如果只使用JSP做视图,可以使用下面这段即可解决: <!-- 视图解释类 --> <bean class="org.springframework.w ...

  8. ubuntu发热问题的解决——显卡驱动的安装

    为了支持自由软件事业,本人作出了“一生中最有意义“的决定:将工作环境从Windows转移到Linux中来!于是装上了ubuntu-10.10,但是用了一小段时间后发现本本发热超大,于是Google百度 ...

  9. HDUOJ---The number of divisors(约数) about Humble Numbers

    The number of divisors(约数) about Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  10. Kafka日志清除策略

    一.更改日志输出级别 config/log4j.properties中日志的级别设置的是TRACE,在长时间运行过程中产生的日志大小吓人,所以如果没有特殊需求,强烈建议将其更改成INFO级别.具体修改 ...