概念
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
参考连接: 单例模式 | 菜鸟教程
代码案例
公共类
public final class StFlag {
public StFlag() {
}
/**
* 饿汉式
*/
public static final String HUNDER="HUNDER";
/**
* 双重检验锁
*/
public static final String DCL="DCL";
/**
* 懒汉式非安全
*/
public static final String LAZYUNSAFE="LAZYUNSAFE";
/**
* 懒汉式安全
*/
public static final String LAZYSAFE="LAZYSAFE";
/**
* 静态内部类
*/
public static final String STATICINNER="STATICINNER";
}
五种单例模式
DCL
/**
* double check locking 双重检验锁
*/
@Slf4j
public class SingletonDCL {
//创建 SingleObject 的一个对象
private volatile static SingletonDCL instance ;
//让构造函数为 private,这样该类就不会被实例化
private SingletonDCL(){}
//获取唯一可用的对象
public static SingletonDCL getInstance(){
if (instance ==null){
synchronized (SingletonDCL.class){
if (instance ==null){
instance=new SingletonDCL();
}
}
}
return instance;
}
public void showMessage(){
log.info("DCL say Hello World!=========="+instance.hashCode());
}
}
饿汉式
/**
* 饿汉式
*/
@Slf4j
public class SingletonHunger {
//创建 SingleObject 的一个对象
private static SingletonHunger instance = new SingletonHunger();
//让构造函数为 private,这样该类就不会被实例化
private SingletonHunger(){}
//获取唯一可用的对象
public static SingletonHunger getInstance(){
return instance;
}
public void showMessage(){
log.info("Hunger say Hello World!=========="+instance.hashCode());
}
}
懒汉安全
/**
* 懒汉安全
*/
@Slf4j
public class SingletonLazySafe {
//创建 SingleObject 的一个对象
private static SingletonLazySafe instance ;
//让构造函数为 private,这样该类就不会被实例化
private SingletonLazySafe(){}
//获取唯一可用的对象
public static synchronized SingletonLazySafe getInstance(){
if (instance ==null){
instance=new SingletonLazySafe();
}
return instance;
}
public void showMessage(){
log.info("Lazy Safe say Hello World!=========="+instance.hashCode());
}
}
懒汉非安全
/**
* 懒汉非安全
*/
@Slf4j
@Service("lazyUnSafe")
public class SingletonLazyUnSafe {
//创建 SingleObject 的一个对象
private static SingletonLazyUnSafe instance ;
//让构造函数为 private,这样该类就不会被实例化
private SingletonLazyUnSafe(){}
//获取唯一可用的对象
public static SingletonLazyUnSafe getInstance(){
if (instance ==null){
instance=new SingletonLazyUnSafe();
}
return instance;
}
public void showMessage(){
log.info("Lazy UnSafe say Hello World!=========="+instance.hashCode());
}
}
静态内部类
/**
* 静态内部类
*/
@Slf4j
@Service("staticInner")
public class SingletonStaticInner {
private static class SingletonStaticInnerClass{
//创建 SingleObject 的一个对象
private static final SingletonStaticInner instance = new SingletonStaticInner();
}
//让构造函数为 private,这样该类就不会被实例化
private SingletonStaticInner(){}
//获取唯一可用的对象
public static SingletonStaticInner getInstance(){
return SingletonStaticInnerClass.instance;
}
public void showMessage(){
log.info("DCL say Hello World!=========="+SingletonStaticInnerClass.instance.hashCode());
}
}
测试类
/**
* 设计模式控制器
*/
@RestController
@RequestMapping("/designPattern")
@Slf4j
public class DesignController {
@GetMapping("/singleton")
public ResponseModel singleton(String singletonType) {
if (StringUtils.isEmpty(singletonType)) {
return new ResponseModel("请输入正确的单例模式类型", 500, null);
}
if (StFlag.DCL.equals(singletonType)) {
SingletonDCL instance = SingletonDCL.getInstance();
instance.showMessage();
return new ResponseModel("双重检验锁单例创建成功", 200, instance.hashCode());
} else if (StFlag.HUNDER.equals(singletonType)) {
SingletonHunger instance = SingletonHunger.getInstance();
instance.showMessage();
return new ResponseModel("饿汉式单例创建成功", 200, instance.hashCode());
} else if (StFlag.LAZYSAFE.equals(singletonType)) {
SingletonLazySafe instance = SingletonLazySafe.getInstance();
instance.showMessage();
return new ResponseModel("懒汉式安全单例创建成功", 200, instance.hashCode());
} else if (StFlag.LAZYUNSAFE.equals(singletonType)) {
SingletonLazyUnSafe instance = SingletonLazyUnSafe.getInstance();
instance.showMessage();
return new ResponseModel("懒汉式非安全单例创建成功", 200, instance.hashCode());
} else if (StFlag.STATICINNER.equals(singletonType)) {
SingletonStaticInner instance = SingletonStaticInner.getInstance();
instance.showMessage();
return new ResponseModel("内部类单例成功", 200, instance.hashCode());
}
return null;
}
}
测试案例
每个请求发两次比较hash值
饿汉式
双重检验锁
懒汉非安全
懒汉式安全
静态内部类
控制台日志
2022-06-16 02:01:18.638 INFO Hunger say Hello World!==========593888302 【http-nio-8081-exec-4】【SingletonHunger:21】
2022-06-16 02:01:29.767 INFO Hunger say Hello World!==========593888302 【http-nio-8081-exec-2】【SingletonHunger:21】
2022-06-16 02:02:13.813 INFO DCL say Hello World!==========682619383 【http-nio-8081-exec-1】【SingletonDCL:31】
2022-06-16 02:02:15.836 INFO DCL say Hello World!==========682619383 【http-nio-8081-exec-9】【SingletonDCL:31】
2022-06-16 02:02:47.905 INFO Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-10】【SingletonLazyUnSafe:24】
2022-06-16 02:02:50.264 INFO Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-8】【SingletonLazyUnSafe:24】
2022-06-16 02:03:11.053 INFO Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-7】【SingletonLazySafe:24】
2022-06-16 02:03:15.359 INFO Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-6】【SingletonLazySafe:24】
2022-06-16 02:03:37.376 INFO DCL say Hello World!==========150313621 【http-nio-8081-exec-5】【SingletonStaticInner:26】
2022-06-16 02:03:39.190 INFO DCL say Hello World!==========150313621 【http-nio-8081-exec-3】【SingletonStaticInner:26】