单例模式在Java和C#中的实现
单例模式算是最常见和最容易理解一种设计模式了。通常是指某一个类只有一实例存在,存在的空间我认为可以理解为该类所在的应用系统内,还有一种是在某一个容器内单一存在,比如像spring的IOC容器(作用域为singleton的bean在容器内是单例存在的),也可以是个简单的HashMap。
单例模式的实现通常分两种,按习惯叫法是饿汉式和懒汉式,这两种的区别主要在于是否延迟初始化。以下是java的饿汉式单例实现:
public class SingletonDemo {
//私有默认构造函数
private SingletonDemo() {}
//已经自行实例化
private static final SingletonDemo single = new SingletonDemo();
public static SingletonDemo getInstance() {
return single;
}
}
C#的实现与这个基本无异,单例的两个实现步骤是一私有化默认构造函数,使得类不可以在外部通过new操作实例化
(注:可以利用反射实例化),
二是内部自身实例化了一个对象供外部使用。那么取得一个SingletonDemo对象只能通过它的静态方法getInstance()了。我们再来看懒汉式的实现:
public class SingletonDemo {
private SingletonDemo() {}
//注意这里没有final
private static SingletonDemo single=null;
public synchronized static SingletonDemo getInstance() {
if (single == null) {
single = new SingletonDemo();
}
return single;
}
}
C#的实现:
public class SingletonDemo
{
private static SingletonDemo instance;
private static object _lock=new object(); private SingletonDemo()
{ } public static SingletonDemo GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new SingletonDemo();
}
}
}
return instance;
}
}
懒汉式主要在于使用时再实例化,可以说二者区别不大。另外懒汉式的一个缺点是要处理多线程调用而产生多个实例的问题,java使用了synchronized同步方法,而C#使用的是lock互斥锁。从这点上来说本人更喜欢饿汉式的简洁。
由上面我们已经知道了两种实现方式区别在于类成员的初始化顺序,我们看看java的成员初始化顺序:静态变量、静态初始化块)>(变量、初始化块)>构造器
很显然我们还可以在静态初始块中为single赋值
static final SingletonDemo single;
static{
single=new SingletonDemo();
//还可以干点其他事,比如启动一个hibernate的SessionFactory,哈哈
}
再看C#的,C#中是没有静态块这一说的,代替它的是静态函数
static readonly SingletonDemo single;
static SingletonDemo()
{
single=new SingletonDemo();
}
这里要提下的是有些人喜欢在静态块中做一些赋值或操作,NHibernate(.net版的hibernate)的示例有这么一段:
public class NHibernateHelper
{
public static readonly Configuration _Configuration;
private const string _CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory _SessionFactory; static NHibernateHelper()
{
log4net.Config.XmlConfigurator.Configure();
_Configuration = new Configuration();
_SessionFactory = _Configuration.Configure().BuildSessionFactory(); }
}
当hibernate配置文件中的数据库配置存在错误时,这里将出现异常,而由于静态函数只在类初始化时运行一次,所以这个异常是不能弥补的,我们只能重启应用再试一次了。
我们也实现一个在容器内的单例,这回来个C#版的吧:
public class DALFactory
{
private static Hashtable cacheDAL = new Hashtable(); public static T createDAL<T>()
{
string CacheKey = typeof(T).FullName;//使用类全名作为key
T dal = (T)cacheDAL[CacheKey];
if (dal == null)
{
lock (cacheDAL)
{
if (dal == null)
{
Type t = typeof(T);
dal = (T)Activator.CreateInstance(t);//反射实例化类
try
{
cacheDAL.Add(CacheKey, dal);
}
catch (ArgumentException) { }
}
}
}
return dal;
}
}
思路很简单,一个键值对容器存放类的实例,使用类全名作为唯一键,要创建类实例时先从容器查找如果有则返回该对象,如果没有则新实例化一个并放入容器。
单例模式在Java和C#中的实现的更多相关文章
- 编写Java程序,中国道教中掌管天宫的最高权力统治者是玉帝(Emperor),我们可以认为玉帝是一个单例模式,在这个场景中,有玉帝和天宫的大臣(Minister)们,大臣每天要上朝参见玉帝,而每一天参
查看本章节 查看作业目录 需求说明: 中国道教中掌管天宫的最高权力统治者是玉帝(Emperor),我们可以认为玉帝是一个单例模式,在这个场景中,有玉帝和天宫的大臣(Minister)们,大臣每天要上朝 ...
- 你真的会写单例模式吗-------Java实现
转载: 你真的会写单例模式吗--Java实现 单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好.用对单例模式,还真得费一番脑筋.本文对Java中常见的单例模式写法做了一个总结,如有错漏 ...
- [转] 你真的会写单例模式吗——Java实现
你真的会写单例模式吗——Java实现 原文:http://www.tuicool.com/articles/MBrUfy6 单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好.用对单例模 ...
- Java并发编程中的设计模式解析(二)一个单例的七种写法
Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...
- 浅谈单例模式及其java实现
单例模式是23种设计模式中比较简单的一种,在此聊一下单例模式. 1.什么是设计模式? 对于没有接触过设计模式的人来说,一听到设计模式这四个字就觉得这个东西很高深莫测,一下子就对这个东西产生了恐惧感,其 ...
- JAVA WEB项目中各种路径的获取
JAVA WEB项目中各种路径的获取 标签: java webpath文件路径 2014-02-14 15:04 1746人阅读 评论(0) 收藏 举报 分类: JAVA开发(41) 1.可以在s ...
- 揭开Java IO流中的flush()的神秘面纱
大家在使用Java IO流中OutputStream.PrintWriter --时,会经常用到它的flush()方法. 与在网络硬件中缓存一样,流还可以在软件中得到缓存,即直接在Java代码中缓存. ...
- JAVA安装过程中出现的“javac不是内部或外部指令”的解决方法
近来重新安装了JAVA,安装过程中出现问题,网上找到解决办法,汇总发布. 解决流程: 1.确定自己的环境变量设置没问题,没有出现遗漏 : . 等情况 (具体环境变量设置百度) 2.环境变量设置后 ,d ...
- Java Web开发中MVC设计模式简介
一.有关Java Web与MVC设计模式 学习过基本Java Web开发的人都已经了解了如何编写基本的Servlet,如何编写jsp及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...
随机推荐
- JMeter学习-005-JMeter 主要组件概要介绍及执行顺序
本文将对 JMeter 主要组件(主要涉及 Threads(Users).Test Fragment.逻辑控制器.配置元件.定时器.前置处理器.Sampler.后置处理器.断言.监听器 十大组件)进行 ...
- imx6 uboot lvds clock
在uboot中添加logo,lvds接口的lcd显示不正常,出现波动.网上说是lvds时钟频率的问题. 使用示波器测量之后,发现频率是60M,而lcd最大频率才46.8M. 因此就需要更改uboot中 ...
- 为什么一个object_id在dba_objects中为什么查不到记录?
SQL> drop table test purge;SQL> create table test (id int,comments CLOB); SQL> select INDEX ...
- java版本区别
java版本区别 点我,点我,Eclipse几个版本号的区别(part1) 点我,点我,Eclipse几个版本号的区别(part2) 点我,点我,Eclipse几个版本号的区别(part3)
- jQuery的dom操作(二)转
addClass() 向匹配的元素添加指定的类名. after() 在匹配的元素之后插入内容. append() 向匹配的元素内部追加内容. appendTo() 向匹配的元素内部追加内容. attr ...
- 给JBoss种蛊分析
JBoss又发现漏洞了,安全圈儿为之一紧. 知道创宇安全研究团队再次本着科普的情怀收集跟JBoss安全相关的材料,为安全行业再出一把力. 这里先给JBoss正下名.通常所说的JBoss,全称是JBos ...
- awk实现 文本内的换行符 为分隔符,输出变为逗号
awk实现 文本内的换行符 为分隔符,输出变为逗号 [liujianzuo@ow2 scripts]$ awk -F $ '{print $0}' ldap_member.log ruanshujun ...
- jiffies和HZ
全局变量jiffies用来记录自系统启动以来产生的节拍的总数.启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值.一秒内时钟中断的次数等于Hz,所以jiffies一秒内增加的 ...
- webService调用的N种方式
一.服务器端代码 新建一个web Service Project工程(貌似普通的java工程也可以,这里不太明白各种webService的框架有什么区别),建立如下的类: package com.bo ...
- iOS让数组内对象执行同一方法
// 让数组中的所有对象都执行removeFromSuperview方法 [self.answerView.subviews makeObjectsPerformSelector:@selector( ...