单例模式在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及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...
随机推荐
- Excl 的一些用法--如何给很多列赋同一个值
1.用鼠标选定要负责的列(多列) 2.在处填写值 3.Ctrl+Enter
- http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
- select下拉框美化
其实用下列CSS就可以解决,原理是将浏览器默认的下拉框样式清除,然后应用上自己的,再附一张向右对齐小箭头的图片即可. select { /*Chrome和Firefox里面的边框是不一样的,所以复 ...
- kinect for windows sdk
https://msdn.microsoft.com/library/dn799271.aspx
- kill 命令详解 系统信号
kill 命令详解 系统信号 参考: 了解Linux的进程与线程 http://www.cnblogs.com/MYSQLZOUQI/p/4234005.html Linux就这个范儿 P532 ...
- int和long int的区别
16位系统:long是4字节,int是2字节32位系统:long是4字节,int是4字节64位系统:long是8字节,int是4字节 long long 占8个字节
- C# MySqlHelper
1.MySql官方提供ADO.NET访问模式的MySql.Data.dll,下载地址:http://dev.mysql.com/downloads/connector/net/ 2.MySqlHelp ...
- SQLSERVER:sqlserver2008r2安装好后,自动提示功能不可以使用
刚安装好的sqlserver2008r2x64,写一些sql时,自动提示功能失效了. 解决排查一: 找到tools->options->Text Editor->Transact-S ...
- wampserver,eclipse,PHPeclipse搭建php开发环境
使用wampserver,安装wampserver后: 1,)进入mysql console,修改mysql密码: 2,) 修改D:\wamp\apps\phpmyadmin3.4.10.1\conf ...
- PostgreSQL Replication之第九章 与pgpool一起工作(7)
9.7 处理故障转移和高可用 可以使用pgpool来解决的一些明显的问题是高可用性和故障转移.一般来讲,有使用pgpool或者不使用pgpool可以用来处理这些问题的各种方法. 9.7.1 使用Pos ...