博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
生产者与消费者的线程问题
阅读量:3957 次
发布时间:2019-05-24

本文共 4887 字,大约阅读时间需要 16 分钟。

问题分析

生产者与消费者之间的联系——货物。这里是大写字母

  1. 设计一个容器,用来存放货物。这里是用栈
  2. 设计一个生产者,随机生产货物,也就是压栈
  3. 设计一个消费者,每次拿出最新生产的货物,也就是弹栈
  4. 设计一个实现类,要它们都工作起来

问题设计

在这里插入图片描述

代码实现

测试类:

package ProducterAndConsumer;//测试类public class testClass {
public static void main(String[] args) {
MyStack
stack = new MyStack<>(); //两个生产者线程 Producer product1 = new Producer(stack,"product1"); Producer product2 = new Producer(stack,"product2"); new Thread(product1).start(); new Thread(product2).start(); //三个消费者线程 Consumer consume1 = new Consumer(stack,"consume1"); Consumer consume2 = new Consumer(stack,"consume2"); Consumer consume3 = new Consumer(stack,"consume3"); new Thread(consume1).start(); new Thread(consume2).start(); new Thread(consume3).start(); }}

生产者线程类:

package ProducterAndConsumer;import java.util.Random;//生产者线程类public class Producer implements Runnable {
private MyStack
stack; private String name; //构造方法 public Producer(MyStack
stack,String name){
this.name = name;//给线程命名 this.stack = stack; } //生产者类中的主要方法:生成随机大写字符压入栈中 public void run() {
while (true){
//括号内可以根据实际情况书写控制条件 try {
Thread.sleep(100); } catch (InterruptedException e) {
e.printStackTrace(); } char randomData = random(); //调用压栈方法 stack.push(randomData); System.out.println(name + ":压入:" + randomData); } } //产生一个随机大写字符 public static char random() {
char[] arrchar = new char[26]; short x = 'A'; for (int i = 0; i < arrchar.length; i++) {
arrchar[i] = (char) x; x++; } int r = new Random().nextInt(26); return arrchar[r]; }}

消费者线程类:

package ProducterAndConsumer;//消费者线程类public class Consumer implements Runnable {
private MyStack
stack; private String name; public Consumer(MyStack
stack,String name){
this.name = name; this.stack = stack; } public void run() {
while (true){
try {
Thread.sleep(50); } catch (InterruptedException e) {
e.printStackTrace(); } //调用弹栈方法 char c = stack.pull(); System.out.println(name + ":弹出:" + c); } }}

容器类:

package ProducterAndConsumer;import java.util.ArrayList;import java.util.Collections;import java.util.LinkedList;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class MyStack
{
//list1为线程安全的集合 List
list1 = Collections.synchronizedList(new ArrayList<>()); LinkedList
list = new LinkedList(list1); //查看最后一个栈内元素 public T top() {
return list.getLast(); }/** *以下为方法一: */ //压栈 public synchronized void push(T h) {
while (list.size() >= 200) {
System.out.println("栈满,不能压栈,等待---"); try {
this.wait(); } catch (InterruptedException e) {
e.printStackTrace(); } } list.addLast(h); this.notifyAll(); } //弹栈 public synchronized T pull() {
while (list.isEmpty()) {
try {
System.out.println("栈空,不能弹栈,等待---"); this.wait(); } catch (InterruptedException e) {
e.printStackTrace(); } } this.notifyAll(); return list.removeLast(); }/** * 以下为方法二: */ Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); //压栈 public void push1(T h) {
try {
lock.lock(); while (list.size() >= 200) {
System.out.println("栈满,不能压栈,等待---"); try {
Thread.sleep(500); condition.await(); } catch (InterruptedException e) {
e.printStackTrace(); } } condition.signalAll(); list.addLast(h); } finally {
lock.unlock(); } } //弹栈 public T pull1() {
T t = null; try {
lock.lock(); while (list.isEmpty()) {
try {
System.out.println("栈空,不能弹栈,等待---"); Thread.sleep(100); condition.await(); } catch (InterruptedException e) {
e.printStackTrace(); } } condition.signalAll(); t = list.removeLast(); } finally {
lock.unlock(); } return t; }}

转载地址:http://odozi.baihongyu.com/

你可能感兴趣的文章
P1-c++函数详解-01函数的默认参数
查看>>
P3-c++函数详解-03函数模板详细介绍
查看>>
P4-c++函数详解-04函数重载,函数模板和函数模板重载,编译器选择使用哪个函数版本?
查看>>
P5-c++内存模型和名称空间-01头文件相关
查看>>
P6-c++内存模型和名称空间-02存储连续性、作用域和链接性
查看>>
P9-c++对象和类-02构造函数和析构函数总结
查看>>
P10-c++对象和类-03this指针详细介绍,详细的例子演示
查看>>
bat备份数据库
查看>>
linux数据库导出结果集且比对 && grep -v ---无法过滤的问题
查看>>
shell函数与自带变量
查看>>
linux下shell获取不到PID
查看>>
sort详解
查看>>
linux,shell中if else if的写法,if elif
查看>>
shell中单引号、双引号、反引号的区别
查看>>
shell脚本死循环方法
查看>>
shell中$*和$@的区别
查看>>
log4cxx 的编译安装过程和使用
查看>>
简单邮件系统程序
查看>>
STL里的multimap使用详解
查看>>
STL 库其中的 std::string用法总结
查看>>