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

思路:

用一个线程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,多线程实在是太恐怖了,哈哈!

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Delphi 的 TThread 对象来实现多线程读取队列的二进制数据,并写入文件。具体步骤如下: 1. 定义一个队列对象,用于存储二进制数据。 ```delphi var Queue: TThreadedQueue<TBytes>; ``` 2. 定义一个继承自 TThread 的子类,用于读取队列的二进制数据,并写入文件。 ```delphi type TFileWriterThread = class(TThread) private FQueue: TThreadedQueue<TBytes>; FFileName: string; public constructor Create(const Queue: TThreadedQueue<TBytes>; const FileName: string); procedure Execute; override; end; constructor TFileWriterThread.Create(const Queue: TThreadedQueue<TBytes>; const FileName: string); begin inherited Create(True); FQueue := Queue; FFileName := FileName; end; procedure TFileWriterThread.Execute; var FileStream: TFileStream; Data: TBytes; begin try // 打开文件流,用于写入数据 FileStream := TFileStream.Create(FFileName, fmCreate); try while not Terminated do begin // 从队列读取二进制数据 if FQueue.PopItem(Data) = wrSignaled then begin // 写入数据到文件 FileStream.WriteBuffer(Data[0], Length(Data)); end; end; finally FileStream.Free; end; except // 异常处理 end; end; ``` 3. 创建多个 TFileWriterThread 对象,启动多个线程进行读取队列和写入文件操作。 ```delphi var FileWriterThreads: array of TFileWriterThread; ThreadCount: Integer; I: Integer; begin // 设置线程数量 ThreadCount := 4; // 创建多个线程对象 SetLength(FileWriterThreads, ThreadCount); for I := 0 to ThreadCount - 1 do begin FileWriterThreads[I] := TFileWriterThread.Create(Queue, 'output.bin'); FileWriterThreads[I].Start; end; // 将二进制数据添加到队列 Queue.PushItem(BytesOf('Hello, world!')); // 等待所有线程退出 for I := 0 to ThreadCount - 1 do begin FileWriterThreads[I].Terminate; FileWriterThreads[I].WaitFor; FileWriterThreads[I].Free; end; end; ``` 在上面的示例,我们创建了 4 个 TFileWriterThread 对象,将它们启动后,将一些二进制数据添加到队列。每个线程会从队列读取数据,并写入到文件。最后,我们等待所有线程退出,释放资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值