单例设计模式
2017-02-22 本文已影响98人
给你添麻烦了
单例设计模式是什么?
单例设计模式是应用最广泛的设计模式,没有之一。当我们需要控制一个类只能被创建出单个对象时,就可以采用单例设计模式。
使用java来实现单例设计模式,普遍有四种实现方式。
- 懒汉式
- 饿汉式
- 双检锁(double check)
- innerclass holder
单例设计模式怎么用?
懒汉式
懒汉式是最常见的单例设计模式的实现方式之一。懒汉代表的含义为lazy-load,意味着当单例对象在项目中,真正被某个业务模块使用时,对象才会被创建。
package com.designpattern.singleton;
/**
* 单例设计模式-懒汉式
*/
public class SingletonLazyMode {
private static SingletonLazyMode shm;
/**
* 私有化构造器
*/
private SingletonLazyMode() {
}
/**
* 获取单例
* 面临并发安全问题,可能会创建多个实例
* 需要对方法进行同步.(独占锁)
*
* @return obj
*/
public static synchronized SingletonLazyMode getSingleton() {
// 在判断处可能发生并发安全问题.
if (shm != null) {
return shm;
} else {
shm = new SingletonLazyMode();
return shm;
}
}
}
懒汉式面临的问题:
getSingleton方法中,判断引用是否为空的逻辑可能发生并发安全问题,可能会创建出复数个对象。
饿汉式
饿汉式与懒汉式刚好是一对反例。一旦饿汉式的class被加载且进行初始化后,单例对象就会被马上创建。
package com.designpattern.singleton;
/**
* 单例设计模式-饿汉式
*/
public class SingletonHungryMode {
private static SingletonHungryMode shm = new SingletonHungryMode();
// 构造器
private SingletonHungryMode() {
}
/**
* 返回实例对象
* 饿汉式避免了并发安全问题,但是却无法实现lazyLoad
*
* @return
*/
public static SingletonHungryMode getSingleton() {
return shm;
}
}
饿汉式面临的问题:
对象无法实现lazy-load。当类被反射调用或设置读取类的静态字段以及执行某个静态方法时,类的静态成员变量就会被初始化。
双检锁
为了解决懒汉式的并发安全问题,又为了减少独占锁而设计出来的一种单例实现方式。
暂无内容
innerclass holder
配合静态内部类实现的单例模式。即使外部类的任何成员被访问,持有外部类单例对象的内部类,直到getInstance方法被调用为止,都不会被初始化。
这种模式即实现了lazy-load,又避免了普通懒汉式的并发安全问题。
package com.designpattern.singleton;
/**
* 单例设计模式-innerclass holder
*/
public class SingletonInnerMode {
/**
* 私有化构造器
*/
private SingletonInnerMode() {
}
/**
* 持有外部类对象的引用.
* 每次被初始化后,sim只会被加载一次.
*/
private static class SingletonInnerHolder {
private static SingletonInnerMode sim = new SingletonInnerMode();
/**
* 私有化构造器
*/
private SingletonInnerHolder() {
}
}
/**
* 获取单例对象.
* getInstance被调用时候,内部类才会被加载
*
* @return
*/
public static SingletonInnerMode getInstanse() {
// 访问成员变量时,内部类的静态成员变量才被初始化
return SingletonInnerHolder.sim;
}
}
总结
- 单例设计模式运用很广泛。
- 在大多数项目中,如果你对性能不是要求特别苛刻,饿汉式可以满足我们的需求。
- 如果你喜欢lazy-load,那么普通的懒汉式在大部分项目中也完全够用。
- innerclass holder实现很巧妙,如果你的某个类在初始化时会进行大量运算,则推荐使用它来解决问题。