当前位置: 首页 > news >正文

设计模式第一课-单例模式(懒汉模式和饿汉模式)

单例模式

个人理解:单例模式实际就是通过类加载的方式获取到一个对象,并且保证这个对象在使用中只有一个,不允许再次被创建

一、懒汉模式

1、懒汉模式的基础写法

代码解释:
(1)、编写LazySingleton类的时候,需要将成员属性设定为static,这样才会是类属性
(2)、重写构造方法,将其设置为private,这样就防止其他人在new这个对象了,防止该类被重复new

package com.example.sheji.singleton.v1;
public class LazySingletonTest {public static void main(String[] args) throws Exception {LazySingleton instance = LazySingleton.getInstance();LazySingleton instance1 = LazySingleton.getInstance();System.out.println(instance);System.out.println(instance1);}
}class LazySingleton{private static LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance()  {if(instance == null){instance =  new LazySingleton();}return instance;}
}

执行结果:可以看到两个对象是一样的,懒汉模式已经基本实现。
但这样的写法在多线程环境下是有问题的!
在这里插入图片描述
当我们改为多线程的方式执行就会出现问题,对象居然不一样了

public class LazySingletonTest {public static void main(String[] args) throws Exception {Thread thread1 = new Thread(() -> {LazySingleton instance = LazySingleton.getInstance();System.out.println(instance);});Thread thread2 = new Thread(() -> {LazySingleton instance = LazySingleton.getInstance();System.out.println(instance);});thread1.start();thread2.start();}
}class LazySingleton{private static LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance()  {if(instance == null){instance =  new LazySingleton();}return instance;}
}

在这里插入图片描述
但如果我们让其中一个线程睡眠200ms呢,会发现对象的值又一样了
在这里插入图片描述
原因如下图,在两个线程都没有休眠的时候,因为执行太快,当第一个线程执行到if(instance == null)里面时,对象还没有new出来,第二个线程也执行到了,所以出现了这种情况
当让第二个线程休眠200ms的时候,第一个线程已经初始化好对象了,第二个线程就不需要初始化了
在这里插入图片描述

2、懒汉模式的升级写法

解释:
(1)、加锁synchronized ,当对象为空时,只允许一个线程先执行,其他线程等待,可以保证对象只被初始化一次
(2)、volatile 关键字,是为了防止指令重排序,防止instance 还没有开辟空间时,先被赋值了

class LazySingleton{private static volatile LazySingleton instance;private LazySingleton(){}public static LazySingleton getInstance()  {if(instance == null){synchronized (LazySingleton.class){if(instance == null){instance =  new LazySingleton();}}}return instance;}
}

测试结果:
在这里插入图片描述

二、饿汉模式

public class HungrySingletionTest {public static void main(String[] args) {
//        HungrySingletion instance1 = HungrySingletion.getInstance();
//        HungrySingletion instance2 = HungrySingletion.getInstance();
//        System.out.println(instance2);
//        System.out.println(instance1);Thread thread = new Thread(() -> {HungrySingletion instance1 = HungrySingletion.getInstance();System.out.println(instance1);});Thread thread1 = new Thread(() -> {HungrySingletion instance2 = HungrySingletion.getInstance();System.out.println(instance2);});thread.start();thread1.start();}
}
class HungrySingletion{private static HungrySingletion instance = new HungrySingletion();private HungrySingletion(){}public static HungrySingletion getInstance() {return instance;}
}

执行结果:
在这里插入图片描述
解释:因为饿汉模式是在利用jvm在加载过程就已经自动初始化好了,所以不论是否使用多线程,都是一个对象

http://www.lryc.cn/news/217236.html

相关文章:

  • Yaml文件详解
  • 【题解 线段树】[蓝桥杯 2022 省 A] 选数异或
  • 宠物喂食器方案智能开发设计
  • chatgpt综述阅读理解
  • XCTF-RSA-2:baigeiRSA2、 cr4-poor-rsa
  • js 根据word文档模板导出内容
  • AIGC | 如何用“Flow”,轻松解决复杂业务问题
  • 多级菜单 树结构 排序 前端 后端 java
  • LAN-Free在数据备份时的应用与优势
  • HTML 文档声明和语言设置
  • 【C++基础知识学习笔记】精华版(复习专用)
  • 探索ChatGPT在学术写作中的应用与心得
  • Android:怎么学习才能更好的进大厂呢?
  • CSS标点符号换行问题
  • jdbc Preparestatement防止SQL注入的原理
  • 如何控制 LLM 的输出格式和解析其输出结果?
  • 【Linux】 ps 命令使用
  • C++二分查找算法的应用:长度递增组的最大数目
  • 提示3D标题编辑器仍在运行怎么解决,以及3D标题编辑器怎么使用
  • 1. PPT高效初始化设置
  • el-cascader级联选择器选中一个全选中问题
  • Opencascad(C++)-创建自定义坐标系
  • MySQL数据库入门到大牛_01_数据库概述
  • Web - Servlet详解
  • postgresql 触发器如何生成递增序列号,从1开始,并且每天重置
  • “第五十九天”
  • IDEA集成Docker插件打包服务镜像与运行【附Docker命令汇总】
  • 【Linux网络编程_TCP/UDP_字节序_套接字 实现: FTP 项目_局域网聊天项目 (已开源) 】.md updata:23/11/03
  • Leetcode刷题详解——全排列
  • JSONP 跨域访问(1), 简介, 原理, 实验, 缺点