确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
实现单例模式的关键点
- 构造函数不对外开放—-Private
- 通过一个静态方法或者枚举返回单利对象
- 确保单例类的对象有且只有一个,尤其是在多线程环境下。
-
枚举类型
原理
根据枚举类型的下述特点,满足单例模式所需的 创建单例、线程安全、实现简洁的需求
饿汉式
原理
依赖 JVM类加载机制,保证单例只会被创建1次,即 线程安全 JVM在类的初始化阶段(即 在Class被加载后、被线程使用前),会执行类的初始化
- 在执行类的初始化期间,JVM会去获取一个锁。这个锁可以同步多个线程对同一个类的初始化
应用场景
除了初始化单例类时 即 创建单例外,继续延伸出来的是:单例对象 要求初始化速度快 & 占用内存小
public class HungrySingleton {
private static final HungrySingleton mSingleton= new HungrySingleton();
//私有构造函数
private HungrySingleton(){
}
//公有的静态函数,对外暴露获取单例对象的接口
public static HungrySingleton getSingleton(){
return mSingleton;
}
}
懒汉式
单例创建时机可控,即有需要时,才 手动创建 单例
class Singleton {
// 1. 类加载时,先不自动创建单例
// 即,将单例的引用先赋值为 Null
private static Singleton ourInstance = null;
// 2. 构造函数 设置为 私有权限
// 原因:禁止他人创建实例
private Singleton() {
}
// 3. 需要时才手动调用 newInstance() 创建 单例
public static Singleton newInstance() {
// 先判断单例是否为空,以避免重复创建
if( ourInstance == null){
ourInstance = new Singleton();
}
return ourInstance;
}
}
懒汉式—同步锁优化
使用同步锁 synchronized锁住创建单例的方法 ,防止多个线程同时调用,
从而避免造成单例被多次创建
写法1
class Singleton {
// 1. 类加载时,先不自动创建单例
// 即,将单例的引用先赋值为 Null
private static Singleton ourInstance = null;
// 2. 构造函数 设置为 私有权限
// 原因:禁止他人创建实例
private Singleton() {
}
// 3. 加入同步锁
public static synchronized Singleton getInstance(){
// 先判断单例是否为空,以避免重复创建
if ( ourInstance == null )
ourInstance = new Singleton();
return ourInstance;
}
}
写法2
// 该写法的作用与上述写法作用相同,只是写法有所区别
class Singleton{
private static Singleton instance = null;
private Singleton(){
}
public static Singleton getInstance(){
// 加入同步锁
synchronized(Singleton.class) {
if (instance == null)
instance = new Singleton();
}
return instance;
}
}