java单例模式懒汉和饿汉C#单例模式之懒汉饿汉
在使⽤某个设计模式之前必须先了解使⽤它的优点:
1、单例模式就是保证在整个应⽤程序的⽣命周期中,在任何时刻,被指定的类只有⼀个实例对象,减少了对象的创建,从⽽减轻了程序内存的开销。
2、单例模式是⼀种常⽤的软件设计模式。在它的核⼼结构中只包含⼀个被称为单例的特殊类。通过单例模式可以保证系统中⼀个类只有⼀个实例⽽且该实例易于外界访问,从⽽⽅便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在⼀个,单例模式是最好的解决⽅案。
3、说⽩了就是保证⼀个类仅有⼀个实例,并提供⼀个该实例的全局访问点⽤于输出实例。
应⽤场景:
1. Windows的Task Manager(任务管理器)就是很典型的单例模式,任何时候只能打开⼀个窗⼝。
2. windows的Recycle Bin(回收站)也是典型的单例应⽤。在整个系统运⾏过程中,回收站⼀直维护着仅有的⼀个实例。
3. ⽹站的计数器,⼀般也是采⽤单例模式实现,否则难以同步。
4. 应⽤程序的⽇志应⽤,⼀般都何⽤单例模式实现,这⼀般是由于共享的⽇志⽂件⼀直处于打开状态,因为只能有⼀个实例去操作,否则内容不好追加。
5. Web应⽤的配置对象的读取,⼀般也应⽤单例模式,这个是由于配置⽂件是共享的资源。
6. 数据库连接池的设计⼀般也是采⽤单例模式,因为数据库连接是⼀种数据库资源。数据库软件系统中使⽤数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是⾮常昂贵的,因为何⽤单例模式来维护,就可以⼤⼤降低这种损耗。
7. 多线程的线程池的设计⼀般也是采⽤单例模式,这是由于线程池要⽅便对池中的线程进⾏控制。
8. 操作系统的⽂件系统,也是⼤的单例模式实现的具体例⼦,⼀个操作系统只能有⼀个⽂件系统。
代码实现(懒汉模式:在第⼀次被引⽤时将⾃⼰实例化):
1.将被调⽤类的构造⽅法定义为私有⽅法,这样其他处的代码就⽆法通过调⽤该类的构造⽅法来实例化该类的对象,只有通过该类提供的静态⽅法来得到该类的唯⼀实例;(防⽌调⽤者直接实例化被调⽤类)
2.在该类内提供⼀个静态⽅法,当我们调⽤这个⽅法时,如果类持有的引⽤不为空就返回这个引⽤,如果类保持的引⽤为空就创建该类的实例并将实例的引⽤赋予该类保持的引⽤。
3.创建访问者对象(⽤于加锁防⽌并发)
4.创建全局访问点(输出实例):所以该⽅法绝对不能是 private不然其他类⽆法调⽤该⽅法,并且必须是静态的⽅法因为本类构造函数为
私有的外部⽆法实例化本类(前⾯已经讲了),所以只能通过类名 .(点)⽅法名来调⽤该⽅法。不然你在创建的这个类就是废类别⼈⽆法使⽤使⽤双重锁来防⽌多线程调⽤出现的并发问题:
当Single为null并且同时有两个线程调⽤
GetInstance⽅法时,他们将都可以通过第
⼀重Single==null的判断,然后由于lock
机制,这两个线程则只有⼀个进⼊,另⼀
个在外排队等候,必须要其中的⼀个进⼊
并出来后,另⼀个才能进⼊。⽽此时如果
没有了第⼆重的Single是否为null的判断,
则第⼀个线程创建了实例,⽽第⼆个线程
还是可以继续在创建新的实例,这就没有
达到单例的⽬的。
5.调⽤
(饿汉模式:加载时就将⾃⼰实例化给调⽤者使⽤)
注意:此时服务对象已经在程序加载时赋值为该类实例(但是只赋值⼀次,因为 static readonly是使⽤静态构造函数赋值)
这样的实现与前⾯的⽰例类似,也是解决了单例模式视图解决的两个基本问题:全局访问和实例化控制,公共静态属性为访问实例提供了⼀个全局访问点。不同之处在于它依赖公共语⾔运⾏库来初始化变量。由于构造⽅法是私有的,因此不能再类本⾝以外实例化Singleton类;因此,变量引⽤的是可以在系统中存在的唯⼀的实例。不过要注意,instance变量标记为readonly,这意味着只能在静态初始化期间或在构造函数中分配变量。由于这种静态初始化的⽅式是在⾃⼰被加载时就将⾃⼰实例化,所以被形象的称之为饿汉式单例类,原先的单例模式处理⽅式是要在第⼀次被引⽤时,才会将⾃⼰实例化,所以就称为懒汉式单例类。
由于饿汉式,即静态初始化的⽅式,它是类⼀加载就实例化的对象,所以要提前占⽤系统资源。然后懒汉式,⼜会⾯临着多线程访问的安全性问题,需要做双重锁定这样的处理才可以保证安全。所以到底使⽤哪⼀种⽅式,取决于实际的需求。从C#
语⾔⾓度来讲,饿汉式的单例类已经⾜够满⾜我们的需求了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论