**
定义
单例模式:一个类有且仅有一个实例,并且自行实例化向整个系统提供。
**
此模式为我们最常用的模式之一,也是设计模式中最简单的模式之一,一般情况下我们在开发中都会用到此模式。下面分为几个点详细了解一下单例模式在我们架构中存在的意义。
一、为什么用
为什么要用单例模式呢?初学者经常会有这样的疑问。 我们知道单例模式是为了保证应用内此类的对象有且只有一个实例,那为什么要保证只有一个实例呢?什么情况下必须保证只有一个实例?在此基础上我们一一解开疑惑。
保证一个实例的主要目的:系统中或应用内只能有一个正在工作的任务。
例如:
- 打印任务:多个打印任务中,只能有一个正在工作;
- Android中的Application,每个单进程的应用程序中有且仅有一个Application对象。在application中定义一个public常量,在activity或service等中就可以通过((XXApplication)getApplication()).XX获取。
- 录音功能:只能有一个录音方法正在执行,但是有多个地方会调用录音,所以我们可以使用单例,保证不会重复录音导致冲突。
可能比较片面,但是简单概括就是保证这个对象中的这个方法正在执行的只有一个,不能多次调用和触发。
二、怎么用
下面全部为java语言
两种方式:饿汉式、懒汉式。
饿汉式代码:
//很饿,在一开始就直接创建了这个对象,效率高,但是浪费资源
private static 类 类名 = new 类();
private 类() {
// 构造方法私有化,保证此类只能通过getInstance()进行创建
}
//注意是静态方法
public static 类 getInstance(){
return 类名;
}
懒汉式代码
//很懒,只有在你要调用它的时候,通过自己写的方法里面来对他实例化,节省资源,但是效率低
private static 类 类名;
private 类() {
// 构造方法私有化,保证此类只能通过getInstance()进行创建
}
//注意是静态方法
public static 类 getInstance(){
//线程不安全,加同步锁;两个if语句提高效率
if (类名 == null) {
synchronized (类.class) {
if (类名 == null) {
类名 = new 类();
}
}
return 类名;
}
此方法在高并发复杂的环境下也会发生几率极低的线程安全问题,所以我们提供了静态内部类实现单例:
//只有第一次执行getInstance()才会调用内部类,缺点是无法传参
public class 类 {
private 类() {
}
public static class 内部类 {
private static final 类 类名 = new 类();
}
public static 类 getInstance() {
return 内部类.类名;
}
}
三、Android源码中的单例模式
在Android系统中,我们经常会通过Context获取系统级别的服务。
//WindowManager的获取
WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//LayoutInflater的获取
LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
这些都是通过Context的getSystemService(String name)获取,其实在Android源码中是以容器实现的单例模式,容器就是systemService,具体方法我们不在这里介绍,有兴趣的朋友可以自行百度。