单例设计模式
单例设计模式介绍
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
单例设计模式的应用场景
1、 网站的计数器,一般采用单例模式实现,否则难以同步。
2、 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
3、 Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
4、 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
5、 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
总结:单例模式应用的场景一般发现在以下条件下
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
单例设计模式的实现
需要做:
(1)将构造方法私有化,使其不能在类的外部通过new关键字实例化该对象。
(2)在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型。
(3)定义一个静态方法返回这个唯一对象。
常见的单例实现有两种:饿汉式(在使用这个类的时候已经将对象创建完毕)和 懒汉式(在调用获取实例方法时才创建对象)
饿汉式
//该类在加载进内存的时候就在堆区创建了一个实例,由于构造方法是私有的,在该类的外部又不能使用构造方法创建实例,调用getInstance方法时就会将在堆区创建的实例返回给用户
public class Singleton {
//将自身实例化设计成一个属性,并直接new
private static Singleton singleton = new Singleton();
//私有化构造方法
private Singleton() {}
//公共静态方法返回该实例
public static Singleton getInstance() {
return singleton;
}
}
/*
优缺点:
-优点
实现起来简单,没有多线程同步问题。
-缺点
当类Singleton被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,
从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被
卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。
*/
懒汉式
//在调用getInstance方法的时候,先判断内存中是否有这个变量,如果有之间返回,没有就创建在返回,保证只有一个
public class Singleton {
//将自身实例化设计成一个属性
private static Singleton singleton;
//私有化构造方法
private Singleton() {}
//公共静态方法返回该实例
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
/*
优缺点:
-优点
实现起来比较简单,当类SingletonTest被加载的时候,静态变量static的instance未被创建并分配
内存空间,当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定
条件下会节约了内存。
-缺点
在多线程环境中,这种实现方法是完全错误的,根本不能保证单例的状态。
*/
线程安全的懒汉式
//在getInstance方法上加synchronized关键字
public class Singleton {
//将自身实例化设计成一个属性
private static Singleton singleton;
//私有化构造方法
private Singleton() {}
//公共静态方法返回该实例
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
/*
优缺点:
-优点:
保证了多线程环境下的安全性问题
-缺点
使用synchronized方法效率降低
*/
DCL双检查锁机制
public class Singleton {
// 将自身实例化对象设置为一个属性,并用static修饰
private static Singleton singleton;
// 构造方法私有化
private Singleton() {}
// 静态方法返回该实例
public static Singleton getInstance() {
// 第一次检查instance是否被实例化出来,如果没有进入if块
if(singleton == null) {
synchronized (Singleton.class) {
// 某个线程取得了类锁,实例化对象前第二次检查instance是否已经被实例化出来,如果没有,才最终实例出对象
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
转载参考:http://www.cnblogs.com/V1haoge/p/6510196.html