说在前面
单列模式是指, 一个对象在上下文中只能存在一个实例/对象,为什么会说实例或者对象因为不想思维被禁锢,希望可以有活跃并且创新的思维。 因为一个只能生成一个对象的类是单例模式, 那么我认为一个单实例的服务也可以认为是一个单列模式。
在严格的意义上来说, 单列模式可能并不是一个设计模式,只是一种实现方式。
单列模式到底可以用在哪里
- 用过Spring的都知道,Spring默认是生成单列Bean的,目的是为了共享资源, 节约空间
- 被描述的对象只有一个时, 比如我们要对 地球,太阳建模, 单列最适合不过了。
单列模式如何实现
在使用java实现单列时不得不关注的点
- 考虑大对象加载问题(毕竟想要描述地球的话,地球还是很大的)我们有在使用时才会被创建的,懒加载模式
- 并发环境下,线程安全问题
不多说,直接上代码,一步到胃。
【实现一IoDH】利用类加载机制,实现懒加载,
public class SinglePattern {
// 测试方法入口,
public static void main(String[] args){
System.out.println("pre");
getSingle();
System.out.println("after");
}
//单列实现
//私有化Constructor
private SinglePattern(){
System.out.println("start single");
}
//内部类完成创建,使用类加载机制确保内部类只被创建一次
static class GetSingle{
static SinglePattern single = new SinglePattern();
static SinglePattern getSingle(){
return single;
}
}
//单列对象获得
public static SinglePattern getSingle(){
return GetSingle.getSingle();
}
}
【实现二DCL双端检锁机制】代码COPY来的, 可以看到,在getInstance()方法使用 synchronized,添加锁。并且在锁竞争之前,进行了过滤
private static SingletonDemo instance = null;
private SingletonDemo(){
}
//(2)DCL (Double Check Lock 双端检锁机制),但仍存在安全隐患,存在指令重排隐患
public static SingletonDemo getInstance(){
if(instance==null){
synchronized (SingletonDemo.class){
if(instance == null){
instance = new SingletonDemo();
}
}
}
return instance;
}
}
一点点扩展
-
类加载机制, 内部类加载机制
-
静态方法,和单列模式的一些区别,
静态方法的优点:
实现简单
如果静态类本身是无状态的,可以在多线程环境下无锁运行
单例模式优点:
可以对事务灵活建模 -
private Instructor 并不能保证对象一定不会在外部被创建,比如反射