设计模式在软件架构设计中被经常使用,掌握常用的设计模式对于设计软件系统非常重要。单 例模式作为设计模式中最简单和常用的一种模式,java中单例模式具有多种实现方式,以下会对各种实现进行解析。
单例模式概念:
顾名思义,单例模式指的是在软件系统运行过程中,某个类只存在一个实例,因此一个类实现 单例模式时需要具备以下3个条件:
1、 类的内部定义一个该类的静态私有成员变量;
2、 构造方法为私有;
3、 提供静态工厂方法,供外部获取类的实例;
单例模式实现方式:
1、懒汉式单例
public class Singleton {
private static Singleton instanee;
private Singleton() {
}
public synchronized static Singleton getlnstance() {
If (instance == null) {
instance = new Singleton();
}
return instance;
}
}
懒汉式单例即在使用使用时才创建类的实例,工厂方法增加类synchronized关键字以保证线 程安全。在多线程访问的环境下,同步方法导致系统性能下降。优点在于,类加载时不用自行 实例化对象,避免加载缓慢。
2,饿汉式单例
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
if (instance = null) {
instance = new Singleton();
return instance;
}
}
饿汉式单例,在类加载式自行实例化对象。优点在于多线程环境下不会出现线程安全问题,因 为类只加载一次。缺点在于,系统加载时消耗额外资源,如果该实例没有使用的情况会造成资 源浪费。
3、双重检测单例
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton():
}
}
}
return instance;
}
}
双重检测锁定(Double-Check Locking)方案属于懒汉式,使用延时加载技术,避免类加载时 任务过重和造成资源浪费,同时将synchronized关键字加在代码块中,减少线程同步锁定以 提升系统性能。instance实例使用了 volatile关键字修饰,主要是避免在多线程环境下由于 编译器进行的重排序操作而导致的线程安全问题。
JVM在创建一个对象时会进行以下步骤:
1、 分配对象内存空间;
2、 初始化对象;
3、 设置instance指向分配的内存地址;
编译器为了优化性能,可能会将2、3操作调换顺序,假设A线程在执行new Singleton()方 法时,由于2、3操作重排序,而初始化对象操作尚未完成时释放了锁。线程B获取锁之后会 发现instance已经不为空,当线程B获取到instance对象后如果直接使用就会出错,原因就 是对象没有进行初始化操作。而volatile关键字能避免重排序,因此能保证线程安全。总体 上来说,双重检测由于加了锁,多线程并发下还是会有效率问题。
4、 枚举单例
public enum Singleton {
INSTANCE
}
枚举单例模式,不会存在线程安全问题,不过在Android平台下,枚举类性能相对较低。
5、静态内部类单例
public class Singleton {
private Singleton() {
}
public static Singleton getInstanceO {
return SingletonFactory.instance;
}
static class SingletonFactory {
private final static Singleton instance = new Singleton();
)
}
静态内部类单例模式是一种比较优秀的实现方式,也是《Effective Java》书中推荐的方式。 一方面,使用延时加载,使用时才进行对象初始化,也不会造成造成资源浪费;另一方面,由 于JVM在类的加载时已经做了同步处理,不会出现线程安全问题。
结束语
文中介绍单例模式的一些基础知识点,以及多种实现方式的优缺点分析。在日常开发中,推荐 使用静态内部类实现单例模式。相对其他设计模式而言,单例模式是非常简单的。
Was this helpful?
0 / 0