单例模式(singleton)
有些时候,允许自由创建某个类的实例没有意义,还可能造成系统性能下降。如果一个类始终只能创建一个实例,则这个类被称为单例类,这种模式就被称为单例模式。
一般建议单例模式的方法命名为:getInstance(),这个方法的返回类型肯定是单例类的类型了。getInstance方法可以有参数,这些参数可能是创建类实例所需要的参数,当然,大多数情况下是不需要的。
单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例。
单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象。
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。
第一种:在声明变量时实例化(也叫饿汉式单例模式),代码如下:
public class Singleton {
private static Singleton instance = new Singleton(); //已经自行实例化
private Singleton(){} //私有的默认构造
public static Singleton getInstance() { //静态工厂方法
return instance;
}
}
第二种:把对象的创建放到方法里面去(也叫懒汉式单例模式),代码如下:
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static synchronized Singleton getInstance() {
//也可以这样写:synchronized public static Singleton getInstance() {
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
各自的优缺点:
第一种饿汉式:
优点:在类加载初始化的时候就创建对象,调用getInstance的时候,没有同步方法,运行时性能较高。
缺点:类加载速度慢,占用太多大的资源空间。
第二种懒汉式:
优点:避免了第一种方式的缺点, 同时,可以在多线程下运行安全。
缺点:因为他使用了锁,在运行中效率慢。
加同步锁提高运行效率的懒汉模式实现方式一:
public class Singleton {
private static Singleton instance;
private final static Object syncLock = new Object();
private Singleton() {
}
public static Singleton getInstance(){
if (instance == null) {
synchronized (syncLock) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
synchronized同步块括号中的锁定对象是采用的一个无关的Object类实例,而不是采用this,因为getInstance是一个静态方法,在它内部不能使用未静态的或者未实例的类对象,因此也可以用下面的方法来实现:
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
不加锁实现单例模式:可以先建立抽象类
/// <summary>
/// 禁止在继承此类的任何类,使用成员变量
/// </summary>
public abstract class Singleton<T> where T : class, new()
{
private static T _instance;
/// <summary>
/// 获取该类的全局唯一实例
/// </summary>
/// <returns></returns>
public static T Instance
{
get
{
if (_instance != null)
{
return _instance;
}
return _instance = new T();
}
}
}
所有需要使用单例模式的实体,只需要继承此抽象类即可
public class MyClass: Singleton<MyClass>
{}