设计模式 - 学习笔记 - 单例模式Singleton Pattern
发布日期:2021-06-30 14:54:13
浏览次数:3
分类:技术文章
本文共 2686 字,大约阅读时间需要 8 分钟。
设计模式 - 学习笔记 - 单例模式Singleton Pattern
学习总结
- 单列的核心就是这东西,我们只想要一份,无论多少人调用它。都是调这个实例。
- 懒汉:调用时才创建实例,能省点是点。
- 饿汉:初始化时直接生成实例,要用时直接调,无需等待。当然如果一直都没调它,那就活活浪费着。。。
- Java实现中考虑线程安全问题,衍生出了8种方式。其实好多是凑数的没啥意义。
- 线程安全问题来自于
懒汉
模式运行时
动态创建
实例,多线程自然就会有撞车风险。饿汉
模式就不存在
线程安全问题了。
应用场景
- 我们经常在工具类中使用单列。
代码示例
饿汉 hungry
1. 经典饿汉模式
天然线程安全。
至于new Singleton()
拆出来放到单独的 static
块中的所谓变种,完全没分别讨论的意义,就是同一个东西。 public class Singleton1 { private static Singleton1 instance = new Singleton1(); private Singleton1 (){ } public static Singleton1 getInstance() { return instance; } public void show(){ System.out.println("饿汉模式"); }}
2. 枚举实现
饿汉。用枚举实现,Effective Java 作者 Josh Bloch 提倡的方式。
public enum Singleton2Enum { INSTANCE; public void show(){ System.out.println("饿汉枚举实现"); }}
3. 客户端
public class SingletonHungryDemo { public static void main(String[] args) { // 经典饿汉 Singleton1.getInstance().show(); // 枚举类 Singleton2Enum.INSTANCE.show(); }}
懒汉 lazy
1. 直接加 synchronized
懒汉:线程安全。synchronized 实现线程安全,但效率低。去掉能提高效率,但会线程不安全。
public class Singleton1ThreadSafe { private static Singleton1ThreadSafe instance; private Singleton1ThreadSafe(){ } public static synchronized Singleton1ThreadSafe getInstance() { if (instance == null) { instance = new Singleton1ThreadSafe(); } return instance; } public void show(){ System.out.println("懒汉:线程安全"); }}
2. 静态内部类
懒汉:静态内部类。利用静态内部类显示调用时才会加载的特性实现懒加载。
public class Singleton2LazyStaticInnerClass { private static class SingletonHolder { private static final Singleton2LazyStaticInnerClass INSTANCE = new Singleton2LazyStaticInnerClass(); } private Singleton2LazyStaticInnerClass(){ } public static final Singleton2LazyStaticInnerClass getInstance() { return SingletonHolder.INSTANCE; } public void show(){ System.out.println("懒汉:静态内部类。利用静态内部类显示调用时才会加载的特性实现懒加载。"); }}
3. 双重检查锁
懒汉:双重检查锁。在方法内部进行了加锁操作,同时使用 volatile 修饰 instance,防止 Java 指令重排,确保当变量 instance 被初始化成实例时,多个线程正确的处理 instance 变量。
public class Singleton3DoubleCheckLock { private volatile static Singleton3DoubleCheckLock singleton; private Singleton3DoubleCheckLock (){ } public static Singleton3DoubleCheckLock getInstance() { if (singleton == null) { synchronized (Singleton3DoubleCheckLock.class) { if (singleton == null) { singleton = new Singleton3DoubleCheckLock(); } } } return singleton; } public void show(){ System.out.println("懒汉:双重检查锁"); }}
参考资料
转载地址:https://jerryjin.blog.csdn.net/article/details/115910599 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月16日 19时18分08秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
日志写入数据库:Logback-DBAppender
2019-05-01
分布式事务原理探究(一)
2019-05-01
MySQL 中基于 XA 实现的分布式事务-学习记录
2019-05-01
Java 并发学习记录之synchronized
2019-05-01
Java 并发学习记录之 wait/notify 机制
2019-05-01
Java 并发学习记录之线程间通信
2019-05-01
Java并发学习记录之volatile
2019-05-01
Docker + mysql主从配置
2019-05-01
Java集合学习之LinkedList
2019-05-01
Spring Security Oauth2 令牌增加额外信息
2019-05-01
Spring Security Oauth2 如何增加自定义授权模式
2019-05-01
logback + Kafka + logstash 集成
2019-05-01
在SpringBoot1.5.x下如何使RedisTokenStore集群化
2019-05-01
Spring Cloud Consul应用下线后,健康检查自动删除无效服务
2019-05-01
spring cloud consul 应用的多实例名的解决
2019-05-01
kafka设置某个topic的数据过期时间
2019-05-01
linux系统编程之信号(五):实时信号与sigqueue函数
2019-05-01
225. 用队列实现栈
2019-05-01
linux系统编程之信号(六):竞态条件与sigsuspend函数
2019-05-01