深入理解Java单例模式和优化多线程任务处理

目录

  • 饿汉模式
  • 懒汉模式
    • 单线程版
    • 多线程版
    • 双重检查锁定
  • 阻塞队列

单例模式能保证某个类在程序中只存在唯一一份实例, 而不会创建出多个实例,并提供一个全局访问点。

饿汉模式

类加载的同时,创建实例。
在这里插入图片描述

class  Singleton {private static final Singleton instance = new Singleton();//将构造方法设为私有,以防止外部通过new关键字创建新的实例。private Singleton() {}public static Singleton getInstance() {return instance;}
}
  • 上述代码定义了一个名为Singleton的类。
  • 在类中定义了一个私有的静态常量instance,它是Singleton类的一个唯一实例。
  • 提供了一个公共的静态方法getInstance(),用于获取Singleton类的唯一实例。

懒汉模式

类加载的时候不创建实例,第一次使用的时候才进行创建。
在这里插入图片描述

单线程版

class Singleton {private static Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

多线程版

上述单线程代码在多线程中就会出现错误,多个线程同时调用getInstance()方法时,就可能导致创建出多个实例是不安全的。这里我们只需要在getInstance()方法中添加synchronized关键字就可解决。

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

双重检查锁定

class Singleton {//volatile关键字保证了instance变量在多线程环境下的可见性。private static volatile Singleton instance = null;private Singleton() {}public synchronized static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class){if (instance == null ){instance = new Singleton();}}}return instance;}
}

双重检查可以这样进行理解:
第一次if先判断实例有没有被创建,如果没被创建就进入第一个if内,使一个线程成功获取锁(其余线程进行阻塞等待),线程获取锁后再次进行判断,判断实例是否创建,没有创建就进行创建。当这个实例创建完了之后,其他竞争到锁的线程就被里层 if 挡住了,也就不会继续创建其他实例。

阻塞队列

阻塞队列能是一种线程安全的数据结构, 并且具有以下特性:

  • 当队列满的时候, 继续入队列就会阻塞, 直到有其他线程从队列中取走元素.
  • 当队列空的时候, 继续出队列也会阻塞, 直到有其他线程往队列中插入元素.

阻塞队列的一种典型应用场景就是生产者消费者模型。

在 Java 标准库中内置了阻塞队列。 如果我们需要在一些程序中使用阻塞队列,直接使用标准库中的即可。

  • BlockingQueue 是一个接口,真正实现的类是 LinkedBlockingQueue
  • put 方法用于阻塞式的入队列,take 用于阻塞式的出队列
  • BlockingQueue 也有 offer, poll, peek 等方法, 但这些方法不带有阻塞特性

下面我们来实现一个阻塞队列:

  • 通过循环队列的方式
  • 使用 synchronized 进行加锁控制
public class BlockingQueue {private int[] arr = new int[1000];private volatile int size = 0;private int tail = 0;private int head = 0;public void put(int value) throws InterruptedException {synchronized (this) {while (size == arr.length) {wait();}arr[tail] = value;tail = (tail + 1) % arr.length;size++;notifyAll();}}public int take() throws InterruptedException {int ret = 0;synchronized (this) {while (size == 0) {wait();}ret = arr[head];head = (head + 1) % arr.length;size--;notifyAll();}return ret;}public static void main(String[] args) throws InterruptedException {BlockingQueue bq = new BlockingQueue();Thread t1 = new Thread(() -> {try {for (int i = 0; i < 10; i++) {bq.put(i);System.out.println("生产者放入:" + i);Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}});t1.start();Thread t2 = new Thread(() -> {try {for (int i = 0; i < 10; i++) {int num = bq.take();System.out.println("消费者取出:" + num);Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}});t2.start();t1.join();t2.join();}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/81852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运维自动化:提高效率的秘诀

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

GEE:快速实现NDVI时间序列NDVI线性趋势和变化敏感性计算(斜率、截距)

作者:CSDN @ _养乐多_ 本博客将向您介绍如何使用Google Earth Engine(GEE)平台来处理Landsat 5、7和8的卫星图像数据,计算NDVI的斜率和截距,以及如何导出这些结果供进一步分析使用。 文章目录 一、代码详解1.1 核心代码详解1.2 核心代码详解1.3 代码框架介绍二、完整代码…

LeetCode: 高频动态规划题目总结 - Python

LeetCode:高频动态规划题目总结 问题描述&#xff1a; LeetCode: 5. 最长回文子串LeetCode: 10. 正则表达式匹配 点 星 . * 那个LeetCode: 22. 括号生成 实际是栈操作LeetCode: 32. 最长有效括号 实际是栈操作LeetCode: 42. 接雨水LeetCode: 44. 通配符匹配 &#xff0c;&…

day06_Java中的流程控制语句

流程控制 简单来讲所谓流程就是完成一件事情的多个步骤组合起来就叫做一个流程。在一个程序执行的过程中&#xff0c;各条语句的执行顺序对程序的结果是有直接影响的。我们必须清楚每条语句的执行流程。而且&#xff0c;很多时候要通过控制语句的执行顺序来实现我们想要的功能…

智慧公厕助力数字强市建设,打造善感知新型信息化公共厕所

随着城市建设的不断发展&#xff0c;智慧公厕作为一个重要的基础设施&#xff0c;正逐渐受到人们的重视。智慧公厕不仅为人们提供舒适的使用环境&#xff0c;更是通过数字化技术的应用&#xff0c;为城市发展注入新的动力。本文将以智慧公厕源头厂家广州中期科技有限公司&#…

@Validated 和 @Valid 的区别,你真的懂吗?SpringBoot 参数校验必知必会!

概述 Valid是使用Hibernate validation的时候使用Validated是只用Spring Validator校验机制使用 说明&#xff1a;java的JSR303声明了Valid这类接口&#xff0c;而Hibernate-validator对其进行了实现 Validation对Valid进行了二次封装&#xff0c;在使用上并没有区别&#xff…

python多线程、进程

1、 并行和并发 &#xff08;1&#xff09;并发&#xff1a;一定周期内&#xff0c;多个任务来回切换执行&#xff0c;宏观上形成“该周期内有多个任务在同时进行”&#xff1b;但同一时间点&#xff0c;只有一个任务在执行。 举例&#xff1a; 你想在2小时内同时完成做饭、扫…

Iterator设计模式

目录 1、示例 1.1 Aggregate接口 1.2 Iterator接口 1.3 Book类 1.4 BookShelf类 1.6 BookShelfIterator 类 1.7 Main类 2、解释Iterator模式中的角色 2.1 Iterator模式的存在意义 2.2 抽象类和接口 2.3 Aggregate 和 Iterator的对应 2.4 容易弄错"下一个"…

QT:使用多窗口做一个登录注册小项目(登录窗口、登录结果窗口、注册窗口)

widget.h(登录窗口) #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QCheckBox> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <Qmap> //模板类class Widget : public QWidget …

rust切片

切片类型写为[T]。 切片是序列的一个片段。 它是动态大小类型&#xff0c;所以要使用切片类型&#xff0c;就必须使用它的指针类型。引用是最常用的指针类型。 [T; n]能隐式转换成[T]。 一、定义切片 &#xff08;一&#xff09;不可变切片 &[T]&#xff0c;共享切片&…

有效的括号(栈的高频面试题)

一、题目描述 题目连接&#xff1a;有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺…

005-第一代光电小工具(一)

第一代光电小工具(一) 文章目录 第一代光电小工具(一)项目介绍大致原理描述核心控件QCustomPlot关于QCustomPlot 播放音频软件截图 关键字&#xff1a; Qt、 Qml、 QCustomPlot、 曲线、 SQLite 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&…

2024届数字IC设计秋招面经-鼎信

背景 985硕士&#xff0c;计算机科班&#xff0c;实验室做cpu设计和fpga算法加速&#xff0c;我做处理器安全方向&#xff0c;有项目。 投递 8.25 没有笔试&#xff0c;两轮面试&#xff0c;直接通知下周一面试&#xff0c;草草的准备了下。 一面 技术面 9.4 不到半小时 …

MySQL修改时间添加时间自动更新

第一种: database.php设置 false改为true;然后看是使用的什么框架 如果是tp5需要数据库是create_time和update_time字段 laravel的话,需要的是created_at和updated_at字段 如果想自定义的话,就在model文件里加上 protected $createTime create_at;// 默认的字段为create_t…

利用spring写一个反向代理

让spring服务器做为一个反向代理&#xff0c;将一些请求转发给其他的服务来完成响应。实现类似于nginx的功能。 思路&#xff1a; 1、写一个Filter来判断路径来转发符合规则的请求(只转发后端请求且符合特定规则的请求) 2、需要判断后端的服务是否存活 3、转发需要将表单之间的…

Python进阶复习-自带库

目录 random库collection库Counter函数namedtuple函数deque函数 itertools库enumarate函数zip函数product函数 random库 random.random():生成一个 0 到 1 之间的随机浮点数。random.uniform(a, b):生成一个在 a 和 b 之间均匀分布的随机浮点数。random.randint(a, b):生成一个…

LED智能家居灯 开关调光 台灯落地灯控制驱动 降压恒流IC AP5191

产品描述 AP5191是一款PWM工作模式,高效率、外围简单、内置功率MOS管&#xff0c;适用于4.5-150V输入的高精度降压LED恒流驱动芯片。输出最大功率150W&#xff0c;最大电流6A。AP5191可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5191 工作频率可以…

sketch for Mac快捷键大全

你可以在sketch中使用键盘快捷键来加快你的设计过程。要使用键盘快捷键&#xff0c;请同时按下下列列表的所有键。有些命令只能根据你在做什么或者你选择了什么才启用&#xff0c;所有把命令分成了下列不同的部分。 sketch下载地址&#xff1a;sketch 破解-Sketch for mac(专业…

# (1462. 课程表 IV leetcode)广搜+拓扑-------------------Java实现

&#xff08;1462. 课程表 IV leetcode&#xff09;广搜拓扑-------------------Java实现 题目表述 你总共需要上 numCourses 门课&#xff0c;课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite &#xff0c;其中 prerequisites[i] [ai, bi] 表示如果你想…

图书管理系统 数据结构先导课暨C语言大作业复习 | JorbanS

问题描述 读取给定的图书文件book.txt中的信息&#xff08;book.txt中部分图书信息如下图所示&#xff09;&#xff0c;完成一个图书信息管理系统&#xff0c;该系统的各个功能模块要求利用菜单选项进行选择。 系统功能要求 图书浏览 读取book.txt中的文件信息并依次输出所…