大家好,我是河海哥,专注于后端,如果可以的话,想做一名code designer而不是普通的coder,一起见证河海哥的成长,您的评论与赞是我的最大动力。
从今天开始就得把设计模式好好弄一弄了,不懂设计模式,看源码一定会是一个遗憾吧,所以先把常用的设计模式好好整理,好好理解。正好边读《设计模式之蝉》边自己总结,
1-1:饿汉
public class Singleton1 {
public static final Singleton1 object = new Singleton1();
private Singleton1() {
}
public static Singleton1 getInstance() {
return object;
}
public void doSomething() {
System.out.println("do something");
}
}
代码很好理解。
- 优点:不会有线程安全问题,因为当类加载的时候他的静态变量会被初始化,这个过程是线程安全的。
- 缺点:如果这种单例多了,当项目起来的时候就会造成很多个单例对象进入内存,启动起来就慢了,其实也问题不大,因为运行好就行。
懒汉的意思就是在需要这个对象的时候,将这个对象丢进内存里面,供别人调用。
1-2-1:有问题的懒汉package com.company.design.singleton;
public class Singleton2 {
public static Singleton2 object = null;
private Singleton2() {
}
public static Singleton2 getInstance() {
if (object == null) {
object = new Singleton2();
}
return object;
}
}
问题主要是并发的时候,两个线程同时判断object==null,就会同时new两个object对象。
1-2-1:并发性能差的懒汉为了实现互斥,添加synchronized 进方法,就可以实现只有一个线程能执行该方法。但是,这对并发效率会影响。
package com.company.design.singleton;
public class Singleton3 {
public static Singleton3 object = null;
private Singleton3() {
}
public synchronized static Singleton3 getInstance() {
if (object == null) {
object = new Singleton3();
}
return object;
}
}
1-2-2:DCL双重检测锁
package com.company.design.singleton;
public class Singleton4 {
public static Singleton4 object = null;
private Singleton4() {
}
public static Singleton4 getInstance() {
if (object == null) {
synchronized (Singleton4.class) {
if (object == null) {
object = new Singleton4();
}
}
}
return object;
}
}
因为并发的时候,只有一开始当object==null的时候,同时对object进行判断,才会有并发问题,只要过了这个时候object不为空刷新回主存,就不存在并发问题了。所以只需要对这么一会儿进行限制。而不是向上一个那样,对getInstance 这个方法全程限制并发。
同时,这个同步锁范围是这个类,进行了两次(object == null)的判定,所以就叫DCL。因为没有后一次的判定,仍然会出现多个对象的情况。ps:以前觉得这种做法很不好,觉得多余,经过两年现在在看,直接妙不可言ok?spring的单例bean里面也用到了这种提高并发的处理,但是不是用的这种单例方式,而是注册表将创建好的bean放在一起,通过注册表来实现单例的效果。
也是一种单例的方式。
package com.company.design.singleton;
public class Singleton5 {
private Singleton5() {
}
public Singleton5 getInstance() {
return InstanceHolder.instance;
}
public static class InstanceHolder {
private static final Singleton5 instance = new Singleton5();
}
}
枚举
还没见过枚举的单例,就当是一种写法储存吧。怎么感觉有点像回字有几种写法。。
1-3:总结:学了一点单例的写法,主要还是DCL的优势,以及简单看了下spring的一点点源码,先弄完设计模式,之后再读spring源码读设计应该会很好吧,期待ing。加油。



