07-单例模式
原型模式
单例(Singleton)模式指一个类只有一个实例,且该类能够自主创建该实例。
单例模式的3个特点:
- 单例类只有一个实例对象。
- 单例对象必须由单例类来创建。
- 单例类对外提供一个访问该单例的全局访问点。
模式的结构与实现
单例模式的主要角色:
- 单例类:包含一个实例且能自行创建这个实例的类。
- 访问类:使用单例的类。
UML类图
实例
需求:竞选美国总统
实现代码步骤如下:
- 懒汉式单例类(单线程)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32//单线程
public class LazySingleton {
public static LazySingleton lazySingleton;
//private 避免类在外部被实例化
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (lazySingleton == null) {
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
//多线程
public class LazySingletonConcurrent {
public static volatile LazySingletonConcurrent lazySingleton;
//private 避免类在外部被实例化
private LazySingletonConcurrent() {
}
public static synchronized LazySingletonConcurrent getInstance() {
if (lazySingleton == null) {
lazySingleton = new LazySingletonConcurrent();
}
return lazySingleton;
}
} - 饿汉式单例类
1
2
3
4
5
6
7
8
9
10
11
12
13//这种写法特点是类在创建的同时就创建好了静态对象供全局使用,以后不再创建新对象。线程安全。
public class HungrySingleton {
public static HungrySingleton hungrySingleton = new HungrySingleton();
//private 避免类在外部被实例化
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return hungrySingleton;
}
} - 双重检查单例类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//线程安全 推荐写法
public class DoubleCheckSingleton {
public static volatile DoubleCheckSingleton doubleCheckSingleton;
private DoubleCheckSingleton() {
}
public static DoubleCheckSingleton getInstance() {
if (doubleCheckSingleton == null) {
synchronized (DoubleCheckSingleton.class) {
if (doubleCheckSingleton == null) {
doubleCheckSingleton = new DoubleCheckSingleton();
}
}
}
return doubleCheckSingleton;
}
} - 静态内部类
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class StaticSingleton {
private StaticSingleton() {
}
private static class StaticSingletonInstance {
private static final StaticSingleton STATIC_SINGLETON = new StaticSingleton();
}
public StaticSingleton getinstance() {
return StaticSingletonInstance.STATIC_SINGLETON;
}
} - 枚举单例类
1
2
3
4
5
6
7public enum EnumSingleton {
INSTANCE;
public EnumSingleton getInstance() {
return INSTANCE;
}
}
总结
优点
- 保证内存例只有一个对象实例,减小内存开销。
- 避免对资源的多重占用。
- 单例模式设置全局访问点,可以优化对共享资源的访问。
缺点
- 扩展困难。
- 并发测试中,调试困难。
- 违反单一原则。
应用场景
- 需要频繁创建的类,使用单例模式可以降低系统内存压力。
- 某些只要求生成一个对象的类。
- 实例类占用系统资源多,实例化时间长,经常使用。
- 频繁实例化,而创建的对象又频繁销毁的类。
- 频繁访问数据库或文件的对象。
- 需要共享的对象。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!