JAVA中多线程读取队列_队列在多线程中的应用

本文介绍了使用Java多线程配合阻塞队列读取文件内容并进行并发处理的方法。线程A负责读取文件内容放入队列,多个线程B同步读取队列数据并发送请求。线程B通过判断队列中的END标识来决定何时结束,并确保每个线程只处理一行数据。实验证明,这种方法显著提高了文件处理速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

用一个线程A去读取文件,将每一行放入到队列Q中;

开启多个线程B去同步的读取队列Q中的数据并发送请求;

线程A和线程B之间通过队列Q进行了交互,队列Q应该是阻塞队列;

线程A的结束,很好说,就是文件读取完毕;那么线程B什么时候结束呢?而且线程B是一组线程,又如何确保他们都正常结束呢?

下面我们先看看线程A的代码吧:

d6ac54c254da6c29689f75feafa17835.png

线程A是一个读取文件形成队列Q的任务,注意下面几点:

构造方法中,队列是外部传入的

定义了一个public属性END,在文件读取最后被放入到了队列中,这是为了通知线程B如果读到了END就可以结束了

放入队列中的方法用的是阻塞式的put

我们在看看线程B的代码:

首先看看属性定义以及构造方法

9c566278deaa4e9d67405f25d2b42b9f.png

同样的,队列是由外部传入构造方法;为了方便,给每一个线程B一个标示。

我们重点关注下线程B的run方法:

5f98981341c6906446901001e18fd93c.png

说明:

首先是一个while循环,如果读取到了队列中的END标示,那么while结束,线程结束

这里取出队首的方法是阻塞式的take

由于队列中的一行,应该只能被一个线程B处理,因此加锁处理取出队首的过程

如果一个线程B读取到了END标示,由于END是读取并删除了,为了其他线程B尽快结束,应该将END继续放入到队列中

主程序部分:

31bf01bf070b7c7c8b128140f0d29d0b.png

在主程序部分,我们定义了阻塞队列及其大小,启动一个线程A,以及多个线程B。

运行结果:

线程[13] 处理167

线程[22] 处理167

线程[28] 处理167

线程[1] 处理167

线程[29] 处理167

线程[27] 处理167

线程[25] 处理167

线程[21] 处理167

线程[18] 处理167

线程[20] 处理167

线程[0] 处理168

线程[4] 处理168

线程[19] 处理168

线程[7] 处理168

线程[15] 处理168

线程[23] 处理168

线程[14] 处理168

线程[3] 处理168

线程[17] 处理168

线程[8] 处理168

线程[5] 处理168

线程[2] 处理168

线程[6] 处理168

线程[24] 处理168

线程[12] 处理168

线程[9] 处理168

线程[11] 处理168

线程[16] 处理168

线程[26] 处理168

线程[10] 处理168

队列 + 多线程同步 读取文件并发请求耗时:16921

可以发现,现在5000多行文件的处理,从原来的8分多钟,变成了现在的16S,多线程实在是太恐怖了,哈哈!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值