java中使用阻塞队列实现生产这与消费这之间的关系
需求如下:
有一个生产者和一个消费者,生产者不断的生产产品,消费这不断的消费产品.产品总数为N.
1.生产顺序按队列的方式,先进先出.
2.生产者和消费这可以同时进行.
3.当生产者生产了N个产品后不能继续生产,消费者消费完后不能继续消费.
4.当生产完成,或者消费完成时,要节约CPU开支(不能使用Sleep);
5.尽量少定义变量,高效率实现.
说明:花了一个小时实现的,如果有不同的意见,希望大家能够指出,共同学习共同进步.
下面说一下我分析的过程:
题目上说:
1.有一个生产者和消费者,这个告诉我们至少要建立两个线程,一个生产者线程,一个消费者线程
2.由生产顺序:先进先出,告诉我们应该使用一个队列.
3.生产和消费可以同时进行:告诉我们至少我们应该考虑并发的问题,我正在生产时你别来消费.
4.要节约CPU开支和生产,消费完成后不能继续生产或者消费:告诉我们而且不能使用Sleep,那么我们应该想到的是,使用wait或者阻塞队列.
抽象一下模型:创建两个线程,一个用于不断的向集合中添加数据,一个不断的向集合中取除数据,如果集合已满,则进行阻塞,如果取数据是集合为空则仍然进行阻塞.
好了下面贴出源代码,如果中间有什么不明白的大家可以查看java jdk帮助文档,上面都有介绍,我这里就不再说了.
生产者:
package cn.yw.daydayinterviewquestion;
import java.util.concurrent.ArrayBlockingQueue;
public class MainTest {
/**
* 程序的入口main方法
*
* @param args
*/
public static void main(String[] args) {
final WorkShop workShop = new WorkShop();
// production
new Thread() {
public void run() {
while(true){
try {
workShop.production();
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
};
}.start();
// customer
new Thread() {
public void run() {
while(true){
try {
workShop.customer();
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
};
}.start();
}
/**
* 车间类
*
* @author yw-tony
*
*/
static class WorkShop {
private int i = 0;
private int countNum = 100;//产品总量
// 产品队列
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1);
//加上互斥技术以防止生产者生产到一半时消费这就消费了.
// 生产方法
public synchronized void production() throws Exception{
if (i < countNum) {
i++;
/*System.out.println("线程" + Thread.currentThread().getName()
+ "准备生产产品." + i);*/
queue.put(i);
System.out.println("线程" + Thread.currentThread().getName()
+ "生产了产品." + i);
}else{
System.out.println("生产完成,等待中....");
queue.take();
}
}
// 消费方法
public synchronized void customer() throws Exception{
/*countNum--;
System.out.println("准备消费产品"+countNum);*/
//消费完成的依据是,消费数等于产品数
Integer c = queue.take();//检索并移除此队列的头部,如果次队列为空,这一直处于等待状态.
System.out.println("消费了产品"+c);
if(c >= 100){
System.out.println("消费完成,正在等待商品产出.....");
}
}
}
}
备注:在这里不用阻塞队列也是可以的,使用线程之间的通信技术一样能够实现,有兴趣的朋友可以写一下,我这里就不写了.
java中使用阻塞队列实现生产这与消费这之间的关系的更多相关文章
- Java中的阻塞队列(BlockingQueue)
1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...
- 多线程编程学习六(Java 中的阻塞队列).
介绍 阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取 ...
- 阻塞队列一——java中的阻塞队列
目录 阻塞队列简介:介绍阻塞队列的特性与应用场景 java中的阻塞队列:介绍java中实现的供开发者使用的阻塞队列 BlockQueue中方法:介绍阻塞队列的API接口 阻塞队列的实现原理:具体的例子 ...
- 聊聊并发(七)——Java中的阻塞队列
3. 阻塞队列的实现原理 聊聊并发(七)--Java中的阻塞队列 作者 方腾飞 发布于 2013年12月18日 | ArchSummit全球架构师峰会(北京站)2016年12月02-03日举办,了解更 ...
- Java中的阻塞队列-ArrayBlockingQueue(一)
最近在看一些java基础的东西,看到了队列这章,打算对复习的一些知识点做一个笔记,也算是对自己思路的一个整理,本章先聊聊java中的阻塞队列 参考文章: http://ifeve.com/java-b ...
- JUC之Java中的阻塞队列及其实现原理
在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...
- Java中的阻塞队列
1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...
- java 中的阻塞队列
1.什么是阻塞队列: 支持阻塞的插入方法,意思是当队列满时,队列会阻塞插入元素的线程,知道队列不满. 支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空. 插入和移除操作的4种处 ...
- Java中的阻塞队列-SynchronousQueue
SynchronousQueue是一个不存储元素的阻塞队列.每一个put操作必须等待一个take操作,否则不能继续添加元素.SynchronousQueue可以看成是一个传球手,负责把生产者线程处理的 ...
随机推荐
- linux下安装apache环境
Centos6.5 64位下安装apache php mysql(安装包版本一定要正确,网上很多都不准,不要用32位的安装包装再64位上,后期有很多问题,下载安装后一定要检出版本,有的网友操蛋,把3 ...
- 英文技术Podcast推荐 - 英语技术一起学
Podcast(播客)是现在比较流行的音.视频RSS订阅媒体.跟大家分享一下我所关注的一些不错的英文技术podcast,大家感兴趣可以订阅,在关注国外最前沿的技术资讯的同时更加锻炼英文听力(有很多需要 ...
- pycharm如何新项目如何不默认创建虚拟环境(吐槽)
最近因为工作上的需要,琢磨了一下python,装了pycharm这个号称史上最好的编辑器,还没开始玩,就被整崩溃了. 因为我是刚开始玩这个,写了很多hello world,所以新建项目的时候很多,不知 ...
- MSys2安装QT5
1. MSYS2 shell # pacman –Syuu 2. Reopen MSYS2 # pacman –Syuu 3.添加国内源 msys64\etc\pacman.d 目录下有三个文件 1. ...
- 《ASP.NET MVC企业实战》(一) MVC开发前奏
一.工具和方法 学到了一些没用过的工具和方法: a)删除多余的using指令并排序:一个类头部的using一般会有很多用不到的,在完成类的编写后,可以右键选择”组织using”来删除没用的using并 ...
- 第一个Django页面(2)
第一个Django页面 1,进入forum项目:熟悉项目里各种文件的作用 2,配置URL:在urls.py里面添加 [url路径与对应的处理函数] 3,编写处理函数:根据urls.py里添加函数的路径 ...
- Java 数据驱动测试
适用场景 测试搜索功能, 基于数据类型需要测多种不同的数据, 比如最大值, 小数, 负数, 字符串, 特异符号等等. 如果直接写代码, 每一种数据类型都需要写一遍代码, 冗长且不方便调试. 如果采用数 ...
- [20171218]varchar2(4000)如何保存.txt
[20171218]varchar2(4000)如何保存.txt --//以前写的,不知道为什么被删除了,现在补上. 如果一行能被存储于一个数据块(data block)中,那么其行头(row hea ...
- JS代码段:VUE下的时间,星期和年月日
不为别的,只为以后复制粘贴方便 data() { return { date: "", time: "", week: "" }; }, / ...
- SQL SERVER孤立帐号的处理
Step1:查询 Use KSHR_F23 Go exec sp_change_users_login @Action='Report' Go Step2:处理 Use KSHR_F23 Go exe ...