单例模式是开发中最常用的设计模式之一。
作用
确保某个类只有一个实例,避免产生多个对象消耗过多的资源。
Android 源码中的单例模式
在 Android 系统中,我们经常会通过 Context 获取系统级别的服务,如 WindowsManagerService、ActivityManagerService 等,更常用的是一个 LayoutInflater 的类,这些服务会在合适的时候以单例的形式注册在系统中,在我们需要的时候就通过 Context 的 getSystemService(String name) 获取。
特点
优点:
(1)由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁的创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
(2)单例模式可以避免对资源的多重占用,例如一个文件操作,由于只有一个实例存在内存中,避免对同一资源文件的同时操作。
(3)单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如,可以设计一个单例类,负责所有数据表的映射处理。
缺点:
(1)单例模式一般没有接口,扩展很困难,若要扩展,只能修改代码来实现。
(2)单例对象如果持有Context,那么很容易引发内存泄露。此时需要注意传递给单例对象的Context最好是Application Context。
实现方式
1. 饿汉式
-
原理
依赖 JVM 类加载机制,保证单例只会被创建1次,即 线程安全。 -
实现
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
2. 枚举单例
- 原理
根据枚举类型的特点,满足单例模式所需的创建单例、线程安全、实现简洁的需求。 - 实现
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
3. 懒汉式(线程不安全)
- 原理
单例创建时机可控,即有需要时,才手动创建单例。 - 实现
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
4. 懒汉式(线程安全)
-
原理
使用同步锁 synchronized 锁住 创建单例的方法 ,防止多个线程同时调用,从而避免造成单例被多次创建 -
实现
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
5. DCL单例(双重检查锁定)
-
原理
在同步锁的基础上,添加1层 if判断:若单例已创建,则不需再执行加锁操作就可获取实例,从而提高性能 -
实现
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
6. 静态内部类单例模式
-
原理
根据 静态内部类 的特性,同时解决了按需加载、线程安全的问题,同时实现简洁。 -
实现
public class Singleton {
private Singleton (){
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
/**
*静态内部类
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
}
7. 使用容器实现单例模式
-
原理
将多种单例类型注入到一个统一的管理类中,在使用时根据key获取对象对应类型的对象。 -
实现
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String,Object>();
private Singleton() { }
public static void registerService(String key, Objectinstance) {
if (!objMap.containsKey(key) ) {
objMap.put(key, instance) ;
}
}
public static ObjectgetService(String key) {
return objMap.get(key) ;
}
}
网友评论