打算把设计模式整一整,不然还是想不到什么时候该用哪种设计模式,在需要的时候想不到,在想到的时候不知道用在哪,所以还是经验缺少和概念模糊的缘故。
单例模式:一个类有且仅有一个实例,并且自行实例化向整个系统提供。
单例模式根据实现方式不同分为:懒汉方式、饿汉方式、静态内部类、枚举方式。
1、懒汉方式:全局的单例实例在第一次被使用时构建。
① 最常见的懒汉方式(线程不安全的):
package com.interview.design.singleton.idler.common;
/**
* @Author: gtd
* @Description:
* @Date: Create in 16:18 2019/1/11
*/
public class SingletonIdler {
private static SingletonIdler singletonIdler;
private SingletonIdler(){
}
public static SingletonIdler getSingletonIdler(){
if (null == singletonIdler){
singletonIdler = new SingletonIdler();
}
return singletonIdler;
}
}
②、线程安全的懒汉方式(双重锁):
package com.interview.design.singleton.idler.safe;
import com.interview.design.singleton.idler.common.SingletonIdler;
/**
* @Author: gtd
* @Description:
* @Date: Create in 16:23 2019/1/11
*/
public class SingletonIdlerSafe {
private static volatile SingletonIdlerSafe singletonIdlerSafe;
private SingletonIdlerSafe(){
}
public static SingletonIdlerSafe getSingletonIdlerSafe(){
if (null == singletonIdlerSafe){
synchronized (SingletonIdlerSafe.class){
if (null == singletonIdlerSafe){
singletonIdlerSafe = new SingletonIdlerSafe();
}
}
}
return singletonIdlerSafe;
}
}
2、饿汉方式:全局的单例实例在类装载时构建,即在加载类的时候就创建类的实例。
饿汉方式(线程安全的):
package com.interview.design.singleton.hungry.common;
/**
* @Author: gtd
* @Description:
* @Date: Create in 16:53 2019/1/11
*/
public class SingletonHungry {
private static final SingletonHungry singletonHungry = new SingletonHungry();
private SingletonHungry(){}
public static SingletonHungry getSingletonHungry(){
return singletonHungry;
}
}
3、静态内部类方式实现:
package com.interview.design.singleton.staticInner;
/**
* @Author: gtd
* @Description:
* @Date: Create in 17:26 2019/1/11
*/
public class SingletonStaticInner {
private SingletonStaticInner(){
}
private static class StaticInner{
private static final SingletonStaticInner singletonStaticInner = new SingletonStaticInner();
}
public static SingletonStaticInner getSingletonStaticInner(){
return StaticInner.singletonStaticInner;
}
}
4、枚举方式实现:
package com.interview.design.singleton.enums;
/**
* @Author: gtd
* @Description:
* @Date: Create in 17:33 2019/1/11
*/
public enum SingletonEnums {
INSTANCES;
public void doSomeThing(){
System.out.println("业务逻辑方法!");
}
}
测试类:
package com.interview.design.singleton;
import com.interview.design.singleton.enums.SingletonEnums;
import com.interview.design.singleton.hungry.SingletonHungry;
import com.interview.design.singleton.idler.common.SingletonIdler;
import com.interview.design.singleton.idler.safe.SingletonIdlerSafe;
import com.interview.design.singleton.staticInner.SingletonStaticInner;
/**
* @Author: gtd
* @Description:
* @Date: Create in 17:33 2019/1/11
*/
public class Test {
public static void main(String[] args) {
SingletonIdler idler = SingletonIdler.getSingletonIdler();
System.out.println(idler.hashCode());
SingletonIdler idler1 = SingletonIdler.getSingletonIdler();
System.out.println(idler1.hashCode());
SingletonIdlerSafe safe = SingletonIdlerSafe.getSingletonIdlerSafe();
System.out.println(safe.hashCode());
SingletonIdlerSafe safe1 = SingletonIdlerSafe.getSingletonIdlerSafe();
System.out.println(safe1.hashCode());
SingletonHungry singletonHungry = SingletonHungry.getSingletonHungry();
System.out.println(singletonHungry.hashCode());
SingletonHungry singletonHungry1 = SingletonHungry.getSingletonHungry();
System.out.println(singletonHungry1.hashCode());
SingletonStaticInner singletonStaticInner = SingletonStaticInner.getSingletonStaticInner();
System.out.println(singletonStaticInner.hashCode());
SingletonStaticInner singletonStaticInner1 = SingletonStaticInner.getSingletonStaticInner();
System.out.println(singletonStaticInner1.hashCode());
SingletonEnums singletonEnums = SingletonEnums.INSTANCES;
System.out.println(singletonEnums.hashCode());
SingletonEnums singletonEnums1 = SingletonEnums.INSTANCES;
System.out.println(singletonEnums1.hashCode());
}
}
下面开始分析一下上面四种实现方式:
1、从线程安全方面考虑,懒汉双重锁方式,饿汉方式,静态内部类方式和枚举方式都是线程安全的。
2、从加载时间上考虑,懒汉方式和静态内部类方式在被调用的时候才去初始化,而饿汉方式和枚举方式在类被加载时就去初始化。这里可以和资源耗费以及应用启动时长关联起来
如果不考虑启动时长的话建议使用饿汉方式。如果考虑延迟加载的话静态内部类和懒汉双重锁都是一种不错的实现方式,枚举用的比较少。
如果在阅读时发现有错误或不足的地方清指正,大家一起学习。
源码上传地址:https://github.com/tiedungao/interviewDesignModelProject