Java项目(5)——单例模式的应用与研究
单例模式是非常别致的一个模式,非常少有人拿它跟其它模式相比,由于,单例模式非常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)——单例模式的应用与研究的更多相关文章
- java项目(学习和研究)
java项目就是研究,不断的对项目进行迭代,把产品做的越来越好,就是research. 自己想着做一个java项目把,可以类似牛客网,想好自己的预期产品,在设计的过程中可以不断改进和扩展,在做这个项目 ...
- JAVA 项目中使用 H2 数据库
为什么要使用H2数据库 H2数据库是可以嵌入到JAVA项目中的,因为只需要导入一个jar包即可,所以非常的方便. 项目中导入H2 将H2的jar包放到classpath里即可,我是用的maven,ma ...
- Android 如何在Eclipse 引入外部纯Java项目(不是打成Jar使用)
应用情景--如标题: 在Eclipse的 “Android启动项目”中引入“外部的纯Java项目”,能运行的只有是基于Android的测试代码才可以. 一直很纳闷,如果外部写好一个Java插件(例如服 ...
- java项目中.classpath,.settings,.project,mymetadata文件的作用
今天犯了一个错误,误修改了本地的.classpath文件,导致项目好多地方报错,之前也没有仔细的研究过项目中的一些生成文件的作用. 今天特此进行记录. 不管我们在eclipse中新建任何的Java项目 ...
- Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境(图文详解)
这篇博客 是在Scala IDEA for Eclipse里手动创建scala代码编写环境. Scala IDE for Eclipse的下载.安装和WordCount的初步使用(本地模式和集群模式) ...
- 关于JAVA项目报表选型过程
本人一直在走.NET技术路线,考虑到后期公司搞JAVA项目,也算是进行技术灾备,开始对JAVA技术进行关注.万事开头难,也是上来一头包.没办法,顶着上吧.上面开始分给我任务了.就是对后期项目报表进行方 ...
- 利用内存分析工具(Memory Analyzer Tool,MAT)分析java项目内存泄露
转载:http://blog.csdn.net/wanghuiqi2008/article/details/50724676 一.开发环境: 操作系统:ubuntu 14.04 IDE:Eclipse ...
- Linux上Makefile管理java项目
前面文章讲到了Linux上通过.spec文件与rpmbuild命令将java程序打包为RPM安装包, 现阶段遇到新的需求: 使用Makefile来操纵java的编译.打包 该需求以前面的内容为基础 可 ...
- maven构建java项目、web项目
maven构建java项目.web项目 一.mvn构建web项目 1安装mvn(包括path) 2命令:mvn archetype:create -DgroupId=cn.edu.sdau.neat ...
随机推荐
- fiddler自动保存请求报文
先来看一张自动保存的请求片段 重点来了,下面是实现的js代码 操作步骤 Fiddler菜单 >> Rules >> Customize Rules 如果提示没有下载Fidd ...
- Swift教程_swift常见问题(0005)_完美解决Cannot override 'dealloc'异常
Swift教程_swift常见问题(0001)_CoreData: warning: Unable to load class named 'xxx' for entity 'xxx' Swift教程 ...
- [Done]SnowFlake 分布式环境下基于ZK构WorkId
Twitter 的 Snowflake 大家应该都熟悉的,先上个图: 时间戳 序列号一般不会去改造,主要是工作机器id,大家会进行相关改造,我厂对工作机器进行了如下改造(估计大家都差不多吧,囧~~~ ...
- win10下Visual Studio 2015,C++ x64编译zlib
前提安装了visual studio 2015 PS.几乎所有方式,x64的编译都会有点坑,鉴于网上的x86编译方式非常的多,所以不再累赘x86的编译方式 zlib下载源: 官网:http: ...
- Scala之Object (apply) dycopy
一.前言 前面学习了Scala的Methods,接着学习Scala中的Object 二.Object Object在Scala有两种含义,在Java中,其代表一个类的实例,而在Scala中,其还是一个 ...
- 两个有序数组求中位数log(m+n)复杂度
leetcode 第4题 中位数技巧: 对于长度为L的有序数组,它的中位数是(a[ceil((L+1)/2)]+a[floor((L+1)/2)])/2 算法原理: 类似三分法求极值 两个人都前进,谁 ...
- su: user tomcat does not exist
http://www.cnblogs.com/allegro/p/5005352.html 问题在于 你的startup.sh 里面设置了 用户,你需要修改为root或者tomcat用户 这是开发 迁 ...
- 用浏览器访问WCF
在开发的时候,为客户端编写代码访问WCF的方式,我们应该比较熟悉,主要是添加一个代理,然后通过这个代理进行访问. 如果用浏览器访问WCF呢?(其实最终是想在JS里面访问)用浏览器访问.测试Web Se ...
- Linux命令-系统健康命令:top
查看系统健康命令 top之后,按1键可以看到每一个cpu使用情况 top 默认是3秒刷新一次,q退出
- ListView回收机制相关分析
最初的分析文档为word,该文档是直接从word文档发布,布局未做详细调整,凑合看吧. 所用源码版本为最新的Android 4.4.2(API 19).更新中…… ListView回收机制相关分析 ...