手撸一个java消息队列(三)

在实现线程安全和持久化的消息队列时,异常处理和性能优化是非常重要的。以下是一些改进措施:
异常处理:确保在读写文件、队列操作等过程中,能够妥善处理可能出现的异常。
性能优化:使用缓冲区和异步写入来减少磁盘I/O操作的开销。
资源管理:确保所有资源(如文件句柄)在使用后都能被正确关闭,以避免资源泄露。
下面是改进后的代码示例:
java
复制
import java.io.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class PersistentQueue {
private LinkedBlockingQueue queue;
private String filePath;
private BufferedWriter writer; // 用于异步写入

public PersistentQueue(String filePath) {this.filePath = filePath;this.queue = new LinkedBlockingQueue<>();initializeWriter();recoverMessages();
}// 异步写入消息到文件
private void initializeWriter() {try {writer = new BufferedWriter(new FileWriter(filePath, true));} catch (IOException e) {throw new RuntimeException("Unable to initialize writer", e);}
}// 将消息添加到队列,并异步写入到文件
public void enqueue(String message) {try {queue.offer(message);new Thread(() -> {try {writer.write(message);writer.newLine();writer.flush(); // 可以选择在此处或在消息消费时flush} catch (IOException e) {e.printStackTrace();}}).start();} catch (Exception e) {e.printStackTrace();}
}// 从队列中取出消息
public String dequeue() {try {return queue.poll(1, TimeUnit.SECONDS); // 1秒超时} catch (InterruptedException e) {Thread.currentThread().interrupt();return null;}
}// 从文件中恢复消息
private void recoverMessages() {File file = new File(filePath);if (file.exists()) {try (BufferedReader reader = new BufferedReader(new FileReader(file))) {String line;while ((line = reader.readLine()) != null) {queue.offer(line);}} catch (IOException e) {throw new RuntimeException("Unable to recover messages", e);}}
}// 确保资源被正确关闭
public void close() throws IOException {queue.clear();if (writer != null) {writer.close();}
}

}

public class Producer implements Runnable {
private PersistentQueue queue;

public Producer(PersistentQueue queue) {this.queue = queue;
}@Override
public void run() {try {for (int i = 0; i < 10; i++) {String message = "Message " + (i + 1);queue.enqueue(message);Thread.sleep(1000);}queue.close(); // 确保资源被关闭} catch (InterruptedException e) {Thread.currentThread().interrupt();} catch (IOException e) {e.printStackTrace();}
}

}

// Consumer 类似于 Producer,使用 queue.dequeue() 来消费消息

public class Main {
public static void main(String[] args) {
String filePath = “messages.txt”;
PersistentQueue queue = new PersistentQueue(filePath);

    Producer producer = new Producer(queue);new Thread(producer).start();// 启动消费者线程等
}

}
在这个改进的版本中,我们添加了以下特性:
异步写入:使用单独的线程来处理消息的写入,以避免阻塞主线程。
资源管理:通过 initializeWriter 和 close 方法来确保 BufferedWriter 资源被正确管理。
超时机制:在 dequeue 方法中添加了超时参数,避免无限期地等待消息。
异常处理:在关键操作中添加了异常处理,确保在发生错误时能够记录并继续执行。
请注意,这个示例代码仍然保持简单,以便于理解。在实际应用中,你可能需要根据具体需求进一步优化和调整异常处理逻辑。

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

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

相关文章

北航第五次数据结构与程序设计编程题复习

北航第五次数据结构与程序设计编程题复习 树叶节点遍历&#xff08;树-基础题&#xff09;计算器&#xff08;表达式计算-表达式树实现&#xff09;服务优化词频统计&#xff08;树实现&#xff09; 树叶节点遍历&#xff08;树-基础题&#xff09; 【问题描述】 从标准输入中…

CTFHUB-SQL注入-报错注入

目录 报错注入概述 报错注入的原理 报错注入的步骤 报错注入的常用函数 实战案例 结论 方法1&#xff1a;updatexml函数 查看数据库名 查看表名 查看表中数据 方法2&#xff1a;extractvalue函数 查看数据库名 查看数据库中的表名 查看表中字段名 查看表中数据 报…

第2回 从0x7c00到0x90000

将数据段寄存器ds的值变成了0x07c0,方便了之后访问内存时利用这个段基址进行寻址,接下来,我们带着这两行代码继续往下看6行: 此时ds寄存器的值已经是0x07c0了,然后用同样的方式将es寄存器的值变成0x9000,接着又把cs寄存器的值变成256。 好的,此时ds,es,cx寄存器的值,都…

CleanMyMac2024最新免费电脑Mac系统优化工具

大家好&#xff0c;我是你们的好朋友——软件评测专家&#xff0c;同时也是一名技术博主。今天我要给大家种草一个超级实用的Mac优化工具——CleanMyMac&#xff01; 作为一个长期使用macOS的用户&#xff0c;我深知系统运行时间长了&#xff0c;缓存文件、日志、临时文件等都会…

LLVM Cpu0 新后端5 静态重定位 动态重定位

想好好熟悉一下llvm开发一个新后端都要干什么&#xff0c;于是参考了老师的系列文章&#xff1a; LLVM 后端实践笔记 代码在这里&#xff08;还没来得及准备&#xff0c;先用网盘暂存一下&#xff09;&#xff1a; 链接: https://pan.baidu.com/s/1yLAtXs9XwtyEzYSlDCSlqw?…

每日一题——Python实现PAT乙级1019 数字黑洞(举一反三+思想解读+逐步优化)

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 点评代码的优缺点&#xff1a; 时间复杂度&#xff1a; 空间复杂度&#…

【类型商店】字符字符串(下)

啊&#xff0c;哈喽&#xff0c;小伙伴们大家好。我是#Y清墨&#xff0c;今天呐&#xff0c;我要介绍的是字符与字符串。 导语 前两期&#xff0c;我们已经懂得了概念&#xff0c;今天来看些函数。 正题 一.增加或连接 &#xff08;1) 后面增加() string s1,s2; //定义 s…

Meta首席AI科学家Yann LeCun指出生成式AI的不足

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

express入门01服务器搭建以及get和post请求的监听

微搭提供了后端API的能力&#xff0c;但是不同的版本收费差别巨大&#xff0c;因为使用的门槛限制了中小企业使用低代码平台。那可不可以既要又要呢&#xff1f;答案是肯定的&#xff0c;那其实掌握一定的后端框架&#xff0c;借助我们在低代码中已经熟练掌握的技能其实是比较容…

影子,介绍一下自己

自述 性格&#xff1a;生活i人&#xff1b;工作e人爱好&#xff1a;崇尚工程师文化&#xff0c;希望科技能帮助每个人更好的生活成长&#xff1a;坚持长期主义&#xff1b;认知提升专业领域&#xff1a;数学&#xff1b;Java后端&#xff1b;大数据&#xff1b;自然语言处理 …

spring和Mybatis的各种查询

文章目录 六**、MyBatis的各种查询功能**6.1、查询一个实体类的对象6.2、查询一个list集合6.3、查询单个数据6.4、查询一条数据为Map集合6.5、查询多条数据为Map集合 七、**特殊SQL的执行**7.1、模糊查询7.2、批量删除7.3、动态设置表名7.4、添加功能获取自增的主键 八、**自定…

OpenCV学习(4.9) OpenCV中的轮廓

1.目标 了解轮廓是什么。学习寻找轮廓&#xff0c;绘制轮廓等您将看到以下功能&#xff1a;**cv.findContours()** &#xff0c;**cv.drawContours()* 2.什么是轮廓 轮廓可以简单地解释为连接具有相同颜色或强度的所有连续点(沿边界)的曲线。轮廓是用于形状分析以及对象检测…

友情提示:lazarus的tsortgrid.autofillcolumns存在BUG

直接在tsortgrid的属性中设置autofillcolumns为true&#xff0c;会提示&#xff1a;123个错误。即使修改为false&#xff0c;编译运行照样会出现上述错误。唯一解决的办法就是删除sortgrid重新添加一个。 代码设置SortGrid1.AutoFillColumns : TRUE不受影响。

【Windows】UWP - Application Frame 窗口句柄溯源

目录 一、问题描述 二、解决方案 三、测试代码 参考文献 本文出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/139574981]。 一、问题描述 当 GUI 线程的窗口属于 Windows/UWP 应用程序时&#xff0c;它们始终由进程 ApplicationFrameHost 托管…

C++ 20新特性之Ranges

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 为什么要引入Ranges 在C 20之前&#xff0c;我们处理容器和迭代器时&#xff0c;通常需要使用一系列的算法和复杂的迭代器操作。这不仅繁琐&…

java aio nio区别

Java AIO&#xff08;Asynchronous I/O&#xff09;和NIO&#xff08;Non-blocking I/O&#xff09;在并发模型、API和适用场景等方面有所不同。具体分析如下&#xff1a; 并发模型 AIO&#xff1a;AIO提供了异步非阻塞的IO操作&#xff0c;通过回调函数来通知IO操作的完成。在…

栈----7-9 括号匹配

给定一串字符&#xff0c;不超过100个字符&#xff0c;可能包括括号、数字、字母、标点符号、空格&#xff0c;编程检查这一串字符中的( ) ,[ ],{ }是否匹配。 输入格式: 输入在一行中给出一行字符串&#xff0c;不超过100个字符&#xff0c;可能包括括号、数字、字母、标点符…

量化投资分析平台 迅投 QMT(六)资产定价绕不过去的BSM模型

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用什么是BSM模型CQF课程介绍模型的五个重要的假设模型公式 我们为啥要学&#xff08;知道&#xff09;这玩意儿呢&#xff1f;隐含波动率&#xff08;Implied Volatility&#xff09…

初阶 《函数》 4. 函数的调用

4. 函数的调用 4.1 传值调用 函数的形参和实参分别占有不同内存块&#xff0c;对形参的修改不会影响实参 4.2 传址调用 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式 这种传参方式可以让函数和函数外边的变量建立起真正的联系&#xff0c;也就是…

Bat脚本专栏目录及索引

文章目录 注释关闭回显和打印pauseerrorlevel 判断刚才的命令是否执行成功%value% 和 !value!的区别脚本名或路径有中文if条件判断语句for 循环语句set 变量设置findstr 搜索指令tasklist 进程列表指令文件操作时间延迟简单应用 注释 REM:: 关闭回显和打印 &#xff1a;字符…