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 ...
随机推荐
- Silverlight 之 断点调试
silverlight程序经常会遇到无法调试的情况,下面来总结解决方案. 一.问题描述 在Silverlight开发过程中,经常时不时的会碰到Silverlight无法调试的问题.如下几种情况: 1. ...
- C# 64位系统调用32位DLL异常解决办法(异常来自HRESULT :0x8007007E)
解决办法如下 1.在IDE中将目标平台设置成x86(VS是在项目的属性->生成->目标平台) 2.如果DLL中调用了其他的DLL,需要将其他的DLL一同编译 3.有时DLL生成时会依赖于I ...
- ViewPage + RadioGroup + Fragment学习
底部是RadioGroup中RadioButton的切换.上面时ViewPage ,能够滑动,假设你们的需求是不须要滑动的话,那就直接用FrameLayout就能够了. 以下将会用两种方式实现.请大家 ...
- 用Navicat Premium 操作MySQL数据库
1. 用Navicat来查看MySQL数据库 打开Navicat Premium–>[连接]–>[MySQL]–>[连接名:新建数据库的名字,此处为“本地”]:[主机: ...
- 网页中的图片查看器viewjs使用
需求分析: 对于网页中的图片进行连续放大(便于用户清晰查看内容).缩小,旋转等操作,可以使用viewjs图片查看器插件实现. viewjs官方网址:https://github.com/fengyua ...
- Hibernate日期映射类型
映 射 类 型 Java类型 标准SQL类型 描 述 date java.util.Date或者java.sql.Date DATE 代表日期,形式为: YYYY-MM-DD time java ...
- 用Java实现AES加密(坑!)
大坑!使用SecureRandom默认的加密方式即SHA1PRNG生成的密码有误,即使使用相同的password来生成,不同runtime或时刻生成的随机密码也有可能不同,造成的错误为javax.cr ...
- 〖Linux〗Android NDK调用已编译好的C/C++动态连接库(so文件)
一.背景:假定已有应用程序zigbeeclient.cpp,内容如下: ... extern "C" { int getresult(int argc, char **argv); ...
- Axure 8.0.0.3312下载地址以及注册码
下载地址: 链接: http://pan.baidu.com/s/1pKMPsJx 密码: gu8t Axure 8.0.0.3312可用注册码(仅供3312版本使用) 用户名:aaa 注册码:2GQ ...
- HOJ 1402 整数划分
HOJ1402 整数划分 http://acm.hit.edu.cn/hoj/problem/view?id=1402 [题目描述] 整数划分是一个经典的问题.希望这道题会对你的组合数学的解题能力有所 ...