欢迎大家下载我个人开发的app安琪花园
介绍
单例模式: 一个类只有一个实例
使用场景: 只有一个实例,避免产生过多 的对象消耗更多的资源
实现方式: 构造函数私有化, 客户端不能重新new, 只能通过定义的静态方法去获取到单例对象
实现方式
- 饿汉式单例模式
这种方式的单例模式实现比较简单,在类加载的时候 就已经创建好了对象,通过对外暴露接口来获取单例对象
比如:
public class A {
private static final A instance = new A();
private A(){}
public static A getInstance(){
return instance;
}
}
- 懒汉式单例模式
懒汉模式其实就是通过调用静态方法获取实例的时候 当没有创建实例的时候 去重新创建实例,当已经创建了实例后,则直接获取之前的实例
比如:
public class A {
private static final A instance;
private A(){}
public static synchronized A getInstance(){
if(instance == null)
instance = new A();
return instance;
}
}
优点: 只有需要的时候去创建实例对象节约 了资源
缺点: 第一次需要去实例对象 反应比较慢。第二,方法前面加了synchronzied的关键字,每次调用 方法都需要同步,则有点浪费资源
- Double CheckLock 单例模式
这种模式获取单例对象能够规避饿汉式和懒汉式的缺点。
具体的实现如下:
public class A {
private volatile static final A instance;
private A(){}
public static synchronized A getInstance(){
if(instance == null){
sycnhronzied(A.class){
if(instance == null)
instance = new A();
}
}
return instance;
}
}
这种实现方式的优点,能在需要的时候去创建对象 ,还能规避懒汉式的每次都需要同步的开销
- 静态内部类单例模式
表达内部类的实现类似于以前写ListView的holder。 具体的代码如下:
public class A {
private static final A instance;
private A(){}
public static synchronized A getInstance(){
return B.instance;
}
private static class B{
private static final A instance = new A();
}
}
这种方式的优点同样能规避掉前面的缺点。当调用getInstance的时候去 去类加载B, 加载B的时候才创建了A的实例。
- 枚举单例
枚举也是单例的一种表现形式。
- 使用容器实例单例模式
使用容器实现单例模式。具体的实例思路是将对象的实例用hashMap存储起来。 然后在获取
某个对象的实例的时候,通过key去hashMap里面取出来。
在android 的源码中一些service就是通过这种方式来实现的。比如:
ActivityManagerService, PackageManagerService。在系统启动的时候 这些实例就已经保存到了map中。
后续在启动某个应用时,如果要获取ActivityManagerService 则调用context.getSystemService(Context.ACTIVITY_SERVICE),其底层是通过从map里面通过这个key获取实例的。
`这里面具体的实现细节就是通过binder来实现的`
总结
上面的6种方式就是一些实现单例模式的方式。把一些常用的必须得记住。
公众号: