多线程: 生产与消费

1.生产者Producer生产produce产品,并将产品放到库存inventory里;同时消费者Consumer从库存inventory里消费consume产品。

2.库存inventory的总量(最大库存量100)是有限的。如果库存inventory满了,生产者不能在库存inventory继续生产produce产品,须等待状态。等待产品被消费者Consumer消费consume了,再往库存inventory生产produce产品。

3.若库存inventory空了,消费者Consumer也须等待状态。等待生产者生产produce产品,再将消费者Consumer唤醒进行消费consume。

补充要求:需要6个线程,分别实现
1.库存为0;2.消费1消费10个(但库存零,则需等待);3.生产2生产5个;4.生产3生产5个(此时库存有10个,则满足消费1的消费;)最终库存仍有0个;5.生产4生产100个);6.生产5生产10个(因库存满了,无法生产,需等待)
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; public class BlockingQueueTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<String>(100);
System.out.println("blockingQueue now contains " + blockingQueue.size() + " unit");
service.submit(new Consumer1(blockingQueue));
gap(blockingQueue);
service.submit(new Productor2(blockingQueue));
gap(blockingQueue);
service.submit(new Productor3(blockingQueue));
gap(blockingQueue);
service.submit(new Productor4(blockingQueue));
gap(blockingQueue);
service.submit(new Productor5(blockingQueue));
gap(blockingQueue); service.shutdown();
}
private static void gap(BlockingQueue<String> blockingQueue) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("blockingQueue now contains " + blockingQueue.size() + " unit");
}
}
class Consumer1 implements Runnable{
BlockingQueue<String> blockingQueue; public Consumer1(BlockingQueue<String> blockingQueue) {
super();
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Consumer1 start: need 10 units");
for(int i = 0; i < 10; i++){
try {
blockingQueue.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Consumer1 end: has got 10 units");
} }
class Productor2 implements Runnable{
BlockingQueue<String> blockingQueue; public Productor2(BlockingQueue<String> blockingQueue) {
super();
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Productor2 start: put 5 units");
for(int i = 0; i < 5; i++){
try {
blockingQueue.put("Object");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Productor2 end: has put 5 units");
} }
class Productor3 implements Runnable{
BlockingQueue<String> blockingQueue; public Productor3(BlockingQueue<String> blockingQueue) {
super();
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Productor3 start: put 5 units");
for(int i = 0; i < 5; i++){
try {
blockingQueue.put("Object");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Productor3 end: has put 5 units");
} }
class Productor4 implements Runnable{
BlockingQueue<String> blockingQueue; public Productor4(BlockingQueue<String> blockingQueue) {
super();
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Productor4 start: put 100 units");
for(int i = 0; i < 100; i++){
try {
blockingQueue.put("Object");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Productor4 end: has put 100 units");
} }
class Productor5 implements Runnable{
BlockingQueue<String> blockingQueue; public Productor5(BlockingQueue<String> blockingQueue) {
super();
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Productor5 start: put 10 units");
for(int i = 0; i < 100; i++){
try {
blockingQueue.put("Object");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Productor5 end: has put 10 units");
} }

每个线程是隔了1s启动的, 结果

blockingQueue now contains 0 unit
Consumer1 start: need 10 units
blockingQueue now contains 0 unit
Productor2 start: put 5 units
Productor2 end: has put 5 units
blockingQueue now contains 0 unit
Productor3 start: put 5 units
Productor3 end: has put 5 units
Consumer1 end: has got 10 units
blockingQueue now contains 0 unit
Productor4 start: put 100 units
Productor4 end: has put 100 units
blockingQueue now contains 100 unit
Productor5 start: put 10 units
blockingQueue now contains 100 unit

												

[Java基础] java多线程关于消费者和生产者的更多相关文章

  1. Java基础技术多线程与并发面试【笔记】

    Java基础技术多线程与并发 什么是线程死锁? ​死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,我们就可以称 ...

  2. java基础---->java中正则表达式二

    跟正则表达式相关的类有:Pattern.Matcher和String.今天我们就开始Java中正则表达式的学习. Pattern和Matcher的理解 一.正则表达式的使用方法 一般推荐使用的方式如下 ...

  3. Java基础-Java中的堆内存和离堆内存机制

    Java基础-Java中的堆内存和离堆内存机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  4. Java基础-Java中的内存分配与回收机制

    Java基础-Java中的内存分配与回收机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. 二.

  5. Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock)

    Java基础-Java中的并法库之重入读写锁(ReentrantReadWriteLock) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在学习Java的之前,你可能已经听说过读 ...

  6. Java基础-Java中的并法库之线程池技术

    Java基础-Java中的并法库之线程池技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是线程池技术 二.

  7. Java基础-Java中23种设计模式之常用的设计模式

    Java基础-Java中23种设计模式之常用的设计模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.设计模式分类 设计模式是针对特定场景给出的专家级的解决方案.总的来说设 ...

  8. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  9. Java基础-Java数据类型

    Java基础-Java数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据类型的作用 数据类型就是一组值,以及这一组值上的操作,数据类型可以决定数据的存储方式,取值范围 ...

  10. 黑马程序员——【Java基础】——多线程

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 (一)进程 正在执行中的程序,每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控 ...

随机推荐

  1. Bcrypt介绍

    Bcrypt把算法版本.计算次数和salt都放到hash值里面去了 Stored in the database, a bcrypt "hash" might look somet ...

  2. [转]在树莓派上搭建LAMP服务

    之前介绍过树莓派上LNMP环境的搭建方法,本文将详细介绍如何在树莓派上配置LAMP服务. 为LAMP,是最流行的服务器配置之一,LAMP的含义是: Linux - 操作系统 Apache - 网络服务 ...

  3. Linux 添加PPA源

    我们在使用Ubuntu安装程序时经常会遇到添加软件源的操作,最常见的是ppa软件源. 例如:sudo add-apt-repository ppa:rvm/smplayer 这就是添加smplayer ...

  4. (转载)常用的Python库

    http://forum.ubuntu.com.cn/viewtopic.php?f=63&t=249573&p=2640959 Tkinter ---- Python默认的图形界面接 ...

  5. vim 源码分析

    vim 源码分析 http://bbs.csdn.net/topics/230031469 Ver7.1  晕.看不明白很正常.  7.1已经很大了.  支持了太多东西. 代码行数那么多(源码压缩了都 ...

  6. Delphi New,Getmem,ReallocMem联系与区别

    来自:http://www.cnblogs.com/jsrgren/archive/2011/10/31/2270353.html ---------------------------------- ...

  7. selenium 找不到元素 (显式等待 和隐式等待的区别)

    selenium自动化页面元素不存在异常发生的原因有一下几点: (1)页面加载时间过慢,需要查找的元素程序已经完成但是页面还未加载成功.此时可以加载页面等待时间. (2)查到的元素没有在当前的ifra ...

  8. 【LeetCode】Reverse digits of an integer

    Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 Have you ...

  9. 使用Derby ij客户端工具

    Derby是开源的.嵌入式的Java数据库程序,ij是Derby提供的客户端工具,相当于其他数据库提供的sqlplus工具. ij是纯Java的程序,不用安装,使用起来就像运行普通的Java应用程序一 ...

  10. AC日记——pigs poj 1149

    POJ - 1149 思路: 最大流: 代码: #include <cstdio> #include <cstring> #include <iostream> # ...