|
|
|
@ -9,6 +9,7 @@ |
|
|
|
|
3. 实现方式 |
|
|
|
|
4. 反序列化和反射 |
|
|
|
|
5. 优缺点 |
|
|
|
|
6. 应用 |
|
|
|
|
|
|
|
|
|
#### 思维导图 |
|
|
|
|
|
|
|
|
@ -16,71 +17,75 @@ |
|
|
|
|
|
|
|
|
|
#### 定义和使用场景 |
|
|
|
|
|
|
|
|
|
定义: |
|
|
|
|
|
|
|
|
|
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 |
|
|
|
|
定义:一个类只允许创建一个对象,那么这个类就是一个单例类。 |
|
|
|
|
|
|
|
|
|
使用场景: |
|
|
|
|
|
|
|
|
|
确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源。 |
|
|
|
|
确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源。除此之外,我们还可以使用单例解决资源访问冲突的问题。 |
|
|
|
|
|
|
|
|
|
#### 实现方式 |
|
|
|
|
|
|
|
|
|
##### 懒汉式 |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
public class SingleTon { |
|
|
|
|
private static SingleTon mInstance; |
|
|
|
|
public class Singleton { |
|
|
|
|
|
|
|
|
|
private static Singleton singleton; |
|
|
|
|
|
|
|
|
|
private SingleTon() { |
|
|
|
|
private Singleton() { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static SingleTon getInstance() { |
|
|
|
|
if (mInstance == null) { |
|
|
|
|
mInstance = new SingleTon(); |
|
|
|
|
public static synchronized Singleton getInstance() { |
|
|
|
|
if (singleton == null) { |
|
|
|
|
singleton = new Singleton(); |
|
|
|
|
} |
|
|
|
|
return mInstance; |
|
|
|
|
return singleton; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
##### 饿汉式 |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
public class SingleTon { |
|
|
|
|
private static SingleTon mInstance = new SingleTon(); |
|
|
|
|
public class Singleton { |
|
|
|
|
|
|
|
|
|
private static Singleton singleton = new Singleton(); |
|
|
|
|
|
|
|
|
|
private SingleTon() { |
|
|
|
|
private Singleton() { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static SingleTon getInstance() { |
|
|
|
|
return mInstance; |
|
|
|
|
public static Singleton getInstance() { |
|
|
|
|
return singleton; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
##### DCL |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
public class SingleTon { |
|
|
|
|
private static volatile SingleTon mInstance; |
|
|
|
|
public class Singleton { |
|
|
|
|
|
|
|
|
|
private SingleTon() { |
|
|
|
|
private static volatile Singleton singleton; |
|
|
|
|
|
|
|
|
|
private Singleton() { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static SingleTon getInstance() { |
|
|
|
|
if (mInstance == null) { |
|
|
|
|
synchronized (SingleTon.class) { |
|
|
|
|
if (mInstance == null) { |
|
|
|
|
mInstance = new SingleTon(); |
|
|
|
|
public Singleton getInstance() { |
|
|
|
|
if (singleton == null) { |
|
|
|
|
synchronized (Singleton.class) { |
|
|
|
|
if (singleton == null) { |
|
|
|
|
singleton = new Singleton(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return mInstance; |
|
|
|
|
return singleton; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
@ -97,16 +102,20 @@ public class SingleTon { |
|
|
|
|
##### 静态内部类 |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
public class SingleTon { |
|
|
|
|
private static volatile SingleTon mInstance; |
|
|
|
|
public class Singleton { |
|
|
|
|
|
|
|
|
|
private Singleton() { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static SingleTon getInstance() { |
|
|
|
|
return SingleHolder.singleTon; |
|
|
|
|
public static Singleton getInstance() { |
|
|
|
|
return SingletonHolder.singleton; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static class SingleHolder { |
|
|
|
|
private static SingleTon singleTon = new SingleTon(); |
|
|
|
|
private static class SingletonHolder { |
|
|
|
|
private static Singleton singleton = new Singleton(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
@ -149,8 +158,6 @@ private SingleTon(){ |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 优缺点 |
|
|
|
|
|
|
|
|
|
优点: |
|
|
|
@ -161,4 +168,43 @@ private SingleTon(){ |
|
|
|
|
|
|
|
|
|
单例类扩张困难,职责过重,一定程度上违背 “单一职责原则”。 |
|
|
|
|
|
|
|
|
|
注意单例对象可能造成的内存泄露问题! |
|
|
|
|
注意单例对象可能造成的内存泄露问题! |
|
|
|
|
|
|
|
|
|
#### 应用 |
|
|
|
|
|
|
|
|
|
在 Android 中,LayoutInflater 使用到了单例模式。 |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
// ContextImpl |
|
|
|
|
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache(); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
final class SystemServiceRegistry { |
|
|
|
|
static { |
|
|
|
|
//... |
|
|
|
|
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, |
|
|
|
|
new CachedServiceFetcher<LayoutInflater>() { |
|
|
|
|
@Override |
|
|
|
|
public LayoutInflater createService(ContextImpl ctx) { |
|
|
|
|
return new PhoneLayoutInflater(ctx.getOuterContext()); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
```java |
|
|
|
|
public static LayoutInflater from(Context context) { |
|
|
|
|
LayoutInflater LayoutInflater = |
|
|
|
|
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
|
|
|
|
if (LayoutInflater == null) { |
|
|
|
|
throw new AssertionError("LayoutInflater not found."); |
|
|
|
|
} |
|
|
|
|
return LayoutInflater; |
|
|
|
|
} |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
其实就是缓存到一个 Map 里面进去取。 |
|
|
|
|
|
|
|
|
|
还有一些单例是比较直观的,比如 AccessibilityManager 以及 Java 中的 Runtime 类等等。 |