本文代码使用的语言为C#,请使用别的语言的同学自行转换为自己习惯的语言
谈到单例模式,首先要明确为什么要使用单例模式?
目的:保证一个类仅有一个实例对象,并且该对象全局共享
方法:构造私有化,属性或方法公开化
1、最简单的单例模式:饿汉式 由于在类被加载的时候就会创建类对象,所以叫做饿汉式
public class Singleton1 {
//饿汉式单例
private static Singleton1 instance = new Singleton1();
private Singleton1() { }
public static Singleton1 Instance() {
return instance;
}
}
2、懒汉式-单例模式 由于我们并不想在程序加载的时候就创建所有的类对象,我们只需要在第一次使用类的时候才创建类对象,这时候便有了懒汉式(你要,我就给,你不要,我不给)
懒汉式一:线程不安全
public class Singleton2 {
private static Singleton2 instance;
private Singleton2() { }
public static Singleton2 Instance{
get{
if (instance == null) {
//如果第一次使用该类,则创建类对象
instance = new Singleton2();
}
return instance;
}
}
}
懒汉式二:线程安全,但是有可能创建多个对象 举例:当两个线程同时访问未使用过的Instance时,两个线程都判断instance为null,这时候,第一个线程进入创建instance对象,而第二个线程等待线程锁打开,有序进入又创建了一次instance对象
public class Singleton3 {
private static Singleton3 instance;
private static readonly object ob = new object();
private Singleton3() { }
public static Singleton3 Instance {
get {
if (instance == null) {
lock (ob) {
instance = new Singleton3();
}
}
return instance;
}
}
}
懒汉式三:线程安全并且对象唯一(推荐使用)
public class Singleton4 {
private static Singleton4 instance;
private static readonly object ob = new object();
private Singleton4() { }
public static Singleton4 Instance {
get {
//先判断一次instance对象是否为null
if (instance == null) {
//加锁
lock (ob) {
//再判断当前instance对象是否为null
if (instance == null) {
instance = new Singleton4();
}
}
}
return instance;
}
}
}
综合以上单例模式,保证线程安全并且满足单例要求的有最简单的饿汉式和懒汉式三这两种方式。
两种模式各有利弊,饿汉式的好处是:非常简单,在类加载的时候便创建了类对象等待使用,所以也不存在线程安全问题
坏处是:有时候我们并不一定在开始就使用到当前类,就会造成资源的浪费
懒汉式的好处是:只有在使用的时候,才会创建类对象,可以有效地利用资源,尽量减少浪费
坏处是:你看到了,代码很啰嗦...