您现在的位置是:首页 > 正文

多线程之阻塞队列BlockingQueue简化生产者消费者模式

2024-01-30 21:44:20阅读 0

在基于阻塞队列构建的生产者—消费者设计中,当数据生成时,生产者把数据放入队列,而当消费者准备处理数据时,将从队列中获取数据。生产者不需要知道消费者的标识或数量,或者它们是否是唯一的生产者,而只需将数据放入队列即可。同样,消费者也不需要知道生产者是谁,或者工作来自何处。BlockingQueue简化了生产者—消费者设计的实现过程,它支持任意数量的生产者和消费者。

因为BlockingQueue内部自己实现了put方法阻塞和take方法阻塞,简化了消费者程序的编码。

下面将之前的例子用阻塞队列实现一下(未控制停止),可以发现它的简便之处。

package com.cc.p_c_stack_mutiList3;

import java.util.List;
import java.util.concurrent.BlockingQueue;
//消费者线程
public class C_Thread extends Thread{
	private BlockingQueue<List<String>> queue;
	public C_Thread(BlockingQueue<List<String>> queue) {
		this.queue = queue;
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(300);
				List<String> next = queue.take();
				System.out.println(Thread.currentThread().getName() + " 消费 " + next.get(0) + "--" + next.get(next.size()-1));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

package com.cc.p_c_stack_mutiList3;

import java.util.List;
import java.util.concurrent.BlockingQueue;
//生产者线程
public class P_Thread extends Thread{
	private BlockingQueue<List<String>> queue;
	public P_Thread(BlockingQueue<List<String>> queue) {
		this.queue = queue;
	}
	
	/*
	 * (非 Javadoc) 
	 * <p>Title: run</p> 
	 * <p>Description: 生产者线程生产数据</p>  
	 * @see java.lang.Thread#run()
	 */
	@Override
	public void run() {
		for (List<String> list : VinDataList.getSizeDataList()) {
			try {
				System.out.println(Thread.currentThread().getName() + " 生产 " + list.get(0) + "--" + list.get(list.size()-1));
				queue.put(list);
				Thread.sleep(300);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

package com.cc.p_c_stack_mutiList3;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
//模拟多线程环境运行
public class Run {
	private final static int BOUND = 1;//共享阻塞队列容量
	
	private final static int CONSUMERS = 5;//消费者数量
	
	public static void main(String[] args) throws InterruptedException {
		VinDataList list = new VinDataList();
		BlockingQueue<List<String>> queue = new LinkedBlockingQueue<List<String>>(BOUND);

		P_Thread pThread = new P_Thread(queue);
		pThread.setName("p-Thread");
		pThread.start();
		
		C_Thread[] cthreads = new C_Thread[CONSUMERS];
		for (int i = 0; i < cthreads.length; i++) {
			cthreads[i] = new C_Thread(queue);
			cthreads[i].setName("c"+(i+1)+"-Thread");
		}
		for (int i = 0; i < cthreads.length; i++) {
			cthreads[i].start();
		}
		
		
	}
}


VinDataList代码相同,省略。
运行结果:
[存在待处理数据,进行生产者消费者模型处理]
p-Thread 生产 1–500
p-Thread 生产 501–1000
c3-Thread 消费 1–500
c1-Thread 消费 501–1000
p-Thread 生产 1001–1500
c5-Thread 消费 1001–1500
p-Thread 生产 1501–2000
c2-Thread 消费 1501–2000
p-Thread 生产 2001–2500
c4-Thread 消费 2001–2500
p-Thread 生产 2501–3000
c1-Thread 消费 2501–3000
p-Thread 生产 3001–3500
c3-Thread 消费 3001–3500
p-Thread 生产 3501–4000
c5-Thread 消费 3501–4000

这只是简易版,一种最常见的生产者—消费者设计模式就是线程池与工作队列的组合,在Executor任务执行框架中就体现了这种模式(后续总结)

网站文章

  • 常用的第三方SDK介绍(搜集中)

    1.验证码 我们开发IT产品时经常要实现注册登录,现在很流行用短信验证码或者语音验证码的形式向客户端发送验证码。 我们开发人员估计都会选用现成的SDK接入实现。比如:创蓝中国 这家专做短信或者语音验证码,或者短信服务。 还有:网易云信 网易云信倒不是专做验证码,可以通过里面的短信模块自己实现验证码。当然网易云信还有其他很多好玩实用的SDK,教学白板就很好玩。 2

    2024-01-30 21:43:48
  • 看完这9本书,让你的编程水平脱胎换骨!(Python篇)

    看完这9本书,让你的编程水平脱胎换骨!(Python篇)

    Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取哈)

    2024-01-30 21:43:41
  • HTML5为什么可以取代Flash(一)

    HTML5为什么可以取代Flash(一)

    AdobeFlash播放器的安全漏洞长久以来都是大麻烦。今夏早些时候,Flash播放器甚至被迫在一周内更新36个安全补丁。 史蒂夫.乔布斯素以反对Flash著称,他在2010年时发表过一份措辞严厉的声明,并拒绝在iPhone上兼容Flash。到2011年,Adobe宣布停止在移动设备上支持Flash播放器。 谷歌最新关于Flash的声明则可能敲响了Flash的丧钟。谷歌Chrome团队宣布将在

    2024-01-30 21:43:33
  • JS 脚本动态执行 动态生成Function / 三个点运算符(扩展运算符)

    最近有个这样的需求,要在我们的后台界面上,让平台使用者可以输入一段脚本,然后在nodejs层,读取这个脚本并执行。并且还要支持自定义输入参数的能力。研究了一下Function的使用,记录在这里。int...

    2024-01-30 21:43:03
  • Python常见面试题总结——个人Python学习经验

    Python常见面试题总结——个人Python学习经验

    这里对Python常见面试题做一个总结,也仅仅是个人的经验,不足之处,还请伙伴们补充!python是如何进行类型转换的?python提供了将变量或值从一种类型转换成另一种类型的内置函数。比如int函数...

    2024-01-30 21:42:56
  • 前端开发工具vscode

    前端开发工具vscode

    开发工具

    2024-01-30 21:42:48
  • K8S Controller技术详解

    K8S Controller技术详解

    1.什么是Controller Controller是在集群上管理和运行容器的对象,Controller是实际存在的,Pod是虚拟的 2.Pod和Controller的关系 Pod是通过Control...

    2024-01-30 21:42:41
  • SpringAop(自定义注解)实现用户操作日志记录

    SpringAop(自定义注解)实现用户操作日志记录

    1.简介 在使用spring完成项目的时候需要完成记录日志,开始以为Spring 的AOP功能,就可以轻松解决,半个小时都不用,可是经过一番了解过后,发现一般的日志记录,只能记录一些简单的操作,例如表...

    2024-01-30 21:42:14
  • XCTF-攻防世界CTF平台-Web类——8、NaNNaNNaNNaN-Batman(JS代码加密)

    XCTF-攻防世界CTF平台-Web类——8、NaNNaNNaNNaN-Batman(JS代码加密)

    目录标题方法一、通过输入得到flag方法二:直接计算得到flag下载附件,查看:是一段乱码的JS代码我们把文件后缀改成.html文件,在浏览器运行看一下代码效果:一个输入框和“OK”按钮,输入“11”...

    2024-01-30 21:42:07
  • 【机器学习】准确率、精确率、召回率、误报率、漏报率概念及公式

    阳性(正)样例P和阴性(负)样例N,将正样本预测为正样本的为True positive(TP),正样本预测为负样本的为False negativ(FN),负样本预测为正样本的为False positi...

    2024-01-30 21:41:59