需求如下:

  有一个生产者和一个消费者,生产者不断的生产产品,消费这不断的消费产品.产品总数为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中使用阻塞队列实现生产这与消费这之间的关系的更多相关文章

  1. Java中的阻塞队列(BlockingQueue)

    1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...

  2. 多线程编程学习六(Java 中的阻塞队列).

    介绍 阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取 ...

  3. 阻塞队列一——java中的阻塞队列

    目录 阻塞队列简介:介绍阻塞队列的特性与应用场景 java中的阻塞队列:介绍java中实现的供开发者使用的阻塞队列 BlockQueue中方法:介绍阻塞队列的API接口 阻塞队列的实现原理:具体的例子 ...

  4. 聊聊并发(七)——Java中的阻塞队列

    3. 阻塞队列的实现原理 聊聊并发(七)--Java中的阻塞队列 作者 方腾飞 发布于 2013年12月18日 | ArchSummit全球架构师峰会(北京站)2016年12月02-03日举办,了解更 ...

  5. Java中的阻塞队列-ArrayBlockingQueue(一)

    最近在看一些java基础的东西,看到了队列这章,打算对复习的一些知识点做一个笔记,也算是对自己思路的一个整理,本章先聊聊java中的阻塞队列 参考文章: http://ifeve.com/java-b ...

  6. JUC之Java中的阻塞队列及其实现原理

    在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...

  7. Java中的阻塞队列

    1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...

  8. java 中的阻塞队列

    1.什么是阻塞队列: 支持阻塞的插入方法,意思是当队列满时,队列会阻塞插入元素的线程,知道队列不满. 支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空. 插入和移除操作的4种处 ...

  9. Java中的阻塞队列-SynchronousQueue

    SynchronousQueue是一个不存储元素的阻塞队列.每一个put操作必须等待一个take操作,否则不能继续添加元素.SynchronousQueue可以看成是一个传球手,负责把生产者线程处理的 ...

随机推荐

  1. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...

  2. [ng:areq] Argument 'XXXXCtrl' is not a function, got undefined

    angular.module('MyApp', []) 这里的[]重复了,以后引入新的controller.js文件会覆盖前面那个,所以此处的[]去掉 .controller('MyCtrl', fu ...

  3. Android常用数据类型转换

    String转int.float.double.byte[].bitmap Int i = Integer.parseInt(str); Float f = Float.parseFloat(str) ...

  4. python 定时修改数据库

    当需要定时修改数据库时,一般我们都选择起一个定时进程去改库.如果将这种定时任务写入业务中,写成一个接口呢,定时进程显得有些不太合适?如果需要定时修改100次数据库,常规做法会启动100个进程,虽然这种 ...

  5. 1.Spring MVC详解

    目录 1.SpringMVC 详细介绍 2.SpringMVC 处理请求流程 3.配置前端控制器 4.配置处理器适配器 5.编写 Handler 6.配置处理器映射器 7.配置视图解析器 8.Disp ...

  6. SQL Server ->> DAC(Dedicated Administrator Connection)专用管理员连接

    专用管理员连接是一种特殊的SQL Server服务器诊断性质的连接,用于在正常或者说标准连接形式无法连接SQL Server服务器的情况下连接到服务器进行服务器性能或者错误诊断.DAC同样支持安全加密 ...

  7. IE push方法,最后一个参数后面不能跟",",否则报语法错误

    var columns = [[]]; columns[0].push( { field: 'ADDNAME', title: '添加人', width: 80, }, { field: 'ADDDT ...

  8. idea 修改单个文件的 编码格式

  9. 50个常用sql语句 网上流行的学生选课表的例子

    50个常用sql语句 建表: --学生表tblStudent(编号StuId.姓名StuName.年龄StuAge.性别StuSex) --课程表tblCourse(课程编号CourseId.课程名称 ...

  10. win10系统如何关掉系统自动更新

    越来越多的电脑使用者都在使用Windows10系统,尽管系统是一代代更新的,但难免有槽点,Windows10系统也不例外,最大的槽点就是“自动更新”的功能.当然,“自动更新”的功能也是相当有用处的.  ...