在生产者/消费者模型中,生产者Producer负责生产数据,而消费者Consumer负责使用数据。多个生产者线程会在同一时间运行,生产数据,并放到内存中一个共享的区域。期间,多个消费者线程读取内存共享区,消费里面的数据。
要求:
1. 针对上面的场景,请创建2个类,一个叫Producer,一个叫Consumer.
2. Producer类继承Thread类,并实现把数据放到内存共享区的功能,这个功能要求是线程安全的。在个Producer类中的run方法中,循环20次,每次把一个整数放到内存共享区中。
3. Consumer类也继承Thread类,并实现在没有冲突的情况下,从内存共享区中获取数据,并在标准输出设备中打印输出。输出的格式为:Consumer thread X retrieved integer Y.
4. 最后,创建一个main class,创建10个Procuder线程和4个消费者线程并启动这些线程。
5. 要求有效代码行数尽量少,最好不超过100行。
我大概的做了一下,以下是我的代码实现:
一. 消费者类
/**
* 消费者类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
class Consumer extends Thread {
private Conn conn;
private int consumerNumber;
public Consumer(Conn conn1, int conNum) {
conn = conn1;
consumerNumber = conNum;
}
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println("Consumer thread " + consumerNumber + " retrieved integer: " + conn.read()); //
try {
sleep((int) (Math.random() * 2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
* 消费者类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
class Consumer extends Thread {
private Conn conn;
private int consumerNumber;
public Consumer(Conn conn1, int conNum) {
conn = conn1;
consumerNumber = conNum;
}
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println("Consumer thread " + consumerNumber + " retrieved integer: " + conn.read()); //
try {
sleep((int) (Math.random() * 2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
二. 生产者类
/**
* 生产者类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
class Producer extends Thread {
private Conn conn;
public Producer(Conn conn1) {
conn = conn1;
}
public void run() {
for (int i = 0; i < 20; i++) {
conn.add(i);
}
}
}
* 生产者类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
class Producer extends Thread {
private Conn conn;
public Producer(Conn conn1) {
conn = conn1;
}
public void run() {
for (int i = 0; i < 20; i++) {
conn.add(i);
}
}
}
三. 线程通信类
/**
* 线程通信类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
class Conn {
private int buffer[] = new int[200]; //10个Procuder线程,需存放200个变量
private int next = 0; //Flags to keep track of our int buffer status
private boolean isFull = false;
private boolean isEmpty = true;
/**
* method to read int
* @return
*/
public synchronized int read() {
while (isEmpty == true) { //We can't read if there is nothing in our int buffer
try {
wait();//we'll exit this when isEmpty turns false
}catch (InterruptedException e) {
e.printStackTrace();
}
}
next--; //decrement the count,since we're going to read one int
if (next == 0) {
isEmpty = true; //Did we read the last letter?
}
isFull = false;
notify();
return (buffer[next]);//return the int to the thread that is reading
}
/**
* method to add integer to the buffer
* @param number
*/
public synchronized void add(int number) {
while (isFull == true ) { //Wait around until there's room to add another letter
try {
wait();//This will exit when isFull turns false
}catch (InterruptedException e) {
e.printStackTrace();
}
}
next++; //add the integer to the next available spot buffer[next]=number;Change the next available spot
if (next == 200) {
isFull = true; //Are we full?
} else {
buffer[next] = number;
}
isEmpty =false;
notify();
}
}
* 线程通信类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
class Conn {
private int buffer[] = new int[200]; //10个Procuder线程,需存放200个变量
private int next = 0; //Flags to keep track of our int buffer status
private boolean isFull = false;
private boolean isEmpty = true;
/**
* method to read int
* @return
*/
public synchronized int read() {
while (isEmpty == true) { //We can't read if there is nothing in our int buffer
try {
wait();//we'll exit this when isEmpty turns false
}catch (InterruptedException e) {
e.printStackTrace();
}
}
next--; //decrement the count,since we're going to read one int
if (next == 0) {
isEmpty = true; //Did we read the last letter?
}
isFull = false;
notify();
return (buffer[next]);//return the int to the thread that is reading
}
/**
* method to add integer to the buffer
* @param number
*/
public synchronized void add(int number) {
while (isFull == true ) { //Wait around until there's room to add another letter
try {
wait();//This will exit when isFull turns false
}catch (InterruptedException e) {
e.printStackTrace();
}
}
next++; //add the integer to the next available spot buffer[next]=number;Change the next available spot
if (next == 200) {
isFull = true; //Are we full?
} else {
buffer[next] = number;
}
isEmpty =false;
notify();
}
}
四. 测试类
/**
* 测试类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
public class ProducerAndConsumerTest {
/**
* @param args
*/
public static void main(String[] args) {
Conn conn = new Conn();
Producer pro1 = new Producer(conn);
Producer pro2 = new Producer(conn);
Producer pro3 = new Producer(conn);
Producer pro4 = new Producer(conn);
Producer pro5 = new Producer(conn);
Producer pro6 = new Producer(conn);
Producer pro7 = new Producer(conn);
Producer pro8 = new Producer(conn);
Producer pro9 = new Producer(conn);
Producer pro10 = new Producer(conn);
Consumer consumer1 = new Consumer(conn, 1);
Consumer consumer2 = new Consumer(conn, 2);
Consumer consumer3 = new Consumer(conn, 3);
Consumer consumer4 = new Consumer(conn, 4);
pro1.start();
pro2.start();
pro3.start();
pro4.start();
pro5.start();
pro6.start();
pro7.start();
pro8.start();
pro9.start();
pro10.start();
consumer1.start();
consumer2.start();
consumer3.start();
consumer4.start();
}
}
* 测试类
* @author Amigo Xie(xiexingxing1121@126.com)
*
*/
public class ProducerAndConsumerTest {
/**
* @param args
*/
public static void main(String[] args) {
Conn conn = new Conn();
Producer pro1 = new Producer(conn);
Producer pro2 = new Producer(conn);
Producer pro3 = new Producer(conn);
Producer pro4 = new Producer(conn);
Producer pro5 = new Producer(conn);
Producer pro6 = new Producer(conn);
Producer pro7 = new Producer(conn);
Producer pro8 = new Producer(conn);
Producer pro9 = new Producer(conn);
Producer pro10 = new Producer(conn);
Consumer consumer1 = new Consumer(conn, 1);
Consumer consumer2 = new Consumer(conn, 2);
Consumer consumer3 = new Consumer(conn, 3);
Consumer consumer4 = new Consumer(conn, 4);
pro1.start();
pro2.start();
pro3.start();
pro4.start();
pro5.start();
pro6.start();
pro7.start();
pro8.start();
pro9.start();
pro10.start();
consumer1.start();
consumer2.start();
consumer3.start();
consumer4.start();
}
}
相关推荐
7. **例程分析**:在提供的"生产者消费者"例程中,可能包含了创建生产者和消费者线程、初始化队列、添加数据到队列、从队列中取出数据、以及使用同步机制保证正确性的代码片段。通过对这些例程的分析和运行,可以...
设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。说明:有界缓冲区内设有20 个存储单元,放入/取出的数据项设定为1‐20 这20 个整型数。设计要求:1)每个生产者和消费者对有界缓冲区...
生产者消费者模式是一种多线程同步的经典设计模式,它在多线程编程中扮演着重要的角色,用于协调生产数据和消费数据的两个并发过程。在本项目“Qt C++11 生产者消费者模式类”中,我们看到利用Qt框架和C++11的新特性...
使用wait()和notify()实现的生产者与消费者模型,可以了解如何使用wait()和notify()进行线程间通信。(上一次上传的代码有一个问题没有考虑到,这次修补了——CSDN没法撤销资源,只能再上传了)
结合System V信号量机制,利用Linux下的多线程库实现了Linux下的操作系统生产者-消费者模型,具体原理可参考博文:: http://blog.csdn.net/Mikeoperfect/article/details/79431642
生产者与消费者模型主要包括两部分:生产者(Producer)和消费者(Consumer)。其中,生产者负责创建数据并将其放入缓冲区,而消费者则从缓冲区中取出数据进行处理。为了确保数据的正确性以及系统的高效运行,必须在...
本主题将深入探讨生产者与消费者模型的Java实现。 生产者与消费者问题的核心是有一个共享资源(例如,一个缓冲区),生产者不断地生产产品并放入缓冲区,而消费者则从缓冲区取出产品进行消费。关键在于确保生产者...
在“LabView图形化编程语言之生产者消费者架构串口数据高速采集”这个主题中,我们将深入探讨如何使用LabView来构建高效的数据采集系统,特别是涉及到串口通信和生产者消费者模式。 首先,让我们理解生产者消费者...
在CSDN.NET博客文章中,作者详细讨论了如何使用线程同步和等待的应用来解决此问题,并提供了示例代码ProducerConsumer.java和ProducerConsumerx.java,这些代码可以帮助读者更好地理解和实现生产者消费者模型。...
消费者-生产者问题描述了一个情境:有若干个生产者(Producer)负责生产物品,而消费者(Consumer)则负责消耗这些物品。问题的关键在于如何有效地协调两者之间的活动,确保不会出现以下两种异常情况: 1. **空缓冲...
生产者消费者问题是多线程编程中的一个经典模型,用于演示如何在并发环境中通过共享资源进行协作。在这个模型中,生产者线程负责生成数据,而消费者线程则负责消费这些数据。问题的关键在于如何保证生产者不会在无处...
- **实验目标**:通过实现一个简单的生产者-消费者模型,加深对进程间同步问题的理解。 - **实验内容**: 1. **模拟一个生产者和一个消费者**:这两个进程共享一个缓冲池,用于存储生产者产生的数据项,消费者从中...
下面是一个简单的生产者消费者模型实现: ```java import java.util.concurrent.ArrayBlockingQueue; public class ProducerConsumerExample { public static void main(String[] args) { ArrayBlockingQueue...
在生产者消费者问题中,可以用于通知生产者何时可以生产,消费者何时可以消费。 使用MFC实现时,我们可以创建这些同步对象,并在线程的运行过程中进行适当的调用,如`CreateMutex`、`WaitForSingleObject`等函数,...
(1)掌握基本的同步互斥算法,理解生产者和消费者同步的问题模型。 (2)了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。 (3)学习使用Windows2000/XP中基本的同步对象,掌握相应的API。 2、...
以下是一个简单的`Qt`生产者-消费者模型的步骤: 1. 创建一个`QMutex`对象,用于保护共享资源(如数据队列)。 2. 创建一个`QWaitCondition`对象,用于线程间的通信。 3. 生产者线程在生产数据前先获取`QMutex`,...
这是一个maven+springmvc+dubbo+zookeeper的模型包括生产者、消费者、接口等。其实现可参考https://blog.csdn.net/mijichui2153/article/details/81102277。
在Java中,我们可以使用`java.util.concurrent`包下的`BlockingQueue`接口来实现生产者-消费者模型。`BlockingQueue`提供了一套线程安全的方法,例如`put()`用于添加元素(生产者操作),`take()`用于获取并移除元素...
例子中,生产者负责将1到1000的整数写入缓冲区,而消费者负责从同一个缓冲区中读取写入的整数并打印出来。因为生产者和消费者是两个同时运行的线程,并且要使用同一个缓冲区进行数据交换,因此必须利用一种机制进行...
为了协调主线程和后台线程之间的交互,避免阻塞UI,我们需要用到消费者-生产者模型。 3. **解决方法:线程同步与信号量**: 在安卓中,我们通常使用`java.util.concurrent`包中的工具类来实现线程同步,如`...