Csharp和Java单例模式

7 篇文章 0 订阅

单例模式经典案例

1、应用场景

全局类频繁的创建和销毁,常用于不同窗体传参问题(优于静态类和构造函数传参)
核心:一个类仅有一个实例 (最简单的设计模式)

  1. 唯一编号问题(道路标识码之类或计数)
  2. 不同窗体传参

2、实现方式

1)懒汉式 (调用了方法才去构造 懒汉)

c# 懒汉式 (多线程安全)

public class Singleton {  
private Singleton()
{
}
private static volatile Singleton _Singleton = null;
private static object Singleton_Lock = new object();
public static Singleton CreateInstance()
{
    if (_Singleton == null)
    {
        lock (Singleton_Lock)
        {
            if (_Singleton == null)
                _Singleton = new Singleton();
        }
    }
    return _Singleton;
}
}

java 懒汉式 (多线程安全)

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}

2)饿汉式 (只要使用类就会被构造,多线程安全)

** c# java 代码同:**

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

3)双检锁/双重校验锁 (多线程安全, 懒汉式 )

c# 双检锁/双重校验锁

    /// <summary>
    /// 单例模式类
    /// </summary>
    public class ApplicationUtil
    {
        private ApplicationUtil ()
	    {}

        /// <summary>
        /// 事件的实例
        /// </summary>
        private static ApplicationUtil instance = null;

        /// <summary>
        /// 线程锁
        /// </summary>
        private static readonly object _lock = new object();
        /// <summary>
        /// 获取对象实例,如果不存在就实例化,否则就直接返回实例
        /// </summary>
        /// <param name="mapControl"></param>
        /// <returns></returns>
        public static ApplicationEventUtil GetInstance()
        {
           //第一次校验
            if (instance == null)
            {
                lock (_lock)
                {
                    //第二次校验
                    if (instance == null)
                    {
                        instance = new ApplicationUtil();
                    }
                }
            }
            return instance;
        }

        /// <summary>
        /// 事件存储中心
        /// </summary>
        Dictionary<string, object> Datas = new Dictionary<string, object>();
        /// <summary>
        /// 设置关键字对应的数据,并激发关联到关键字上的事件
        /// </summary>
        /// <param name="cKey">事件关键字</param>
        /// <param name="cData">关键字关联的数据</param>
        public void SetData(string cKey, object cData)
        {

            //存在关键字的话,设置关键字
            if (Datas.ContainsKey(cKey))
            {
                try
                {
                    Datas[cKey] = cData;
                }
                catch 
                {
                }
                return;
            }

            //不存在的新建关键字
            try
            {
                Datas.Add(cKey, cData);
            }
            catch { }
        }
        /// <summary>
        /// 获取关键字关联的数据
        /// </summary>
        /// <param name="cKey">关键字</param>
        /// <returns>返回关键字数据,无此关键字返回null</returns>
        public object GetData(string cKey)
        {
            try
            {
                if (Datas.ContainsKey(cKey))
                {
                    return Datas[cKey];
                }
            }
            catch 
                { 
                    return null;
                }
        }
        
        /// <summary>
        ///  移除相应的键
        /// </summary>
        /// <param name="cKey"></param>
        public void RemoveData(string cKey)
        {
            if (Datas.Keys.Contains(cKey))
            {
                Datas.Remove(cKey);
            }
        }
    }
}

java 双检锁/双重校验锁

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    //第一次校验
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        //第二次校验
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

3、结论:

1)第三种模式为经典模式,使用频率最高
2)双检锁/双重校验锁 (推荐使用,线程安全,双锁机制,性能高)

在java中使用双重校验锁,注意:
1、volatile 关键词不可缺少
2、以上同使用映射的方式可破坏单例模式,以上方式并非绝对安全的单例模式,通常开发中,无需考虑映射破坏单例模式的问题,遇到此类问题,您可以使用枚举的方式创建单例模式解决此问题(略)

4、声明

1)文章来源于项目实践,如存在问题或疑问,请留言,感谢您的阅读,谢谢!
2)转载请标注来源,感谢您的阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值