如何实现生产者消费者模式

生产/消费者问题是个非常典型的多线程问题,涉及到的对象包括“生产者”、“消费者”、“仓库”和“产品”。他们之间的关系如下:

① 生产者仅仅在仓储未满时候生产,仓满则停止生产。

② 消费者仅仅在仓储有产品时候才能消费,仓空则等待。

③ 当消费者发现仓库没产品可消费时候会通知生产者生产。

④ 生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

wait/notify/notifyAll实现和用LockCondition实现。

用wait/notify/notifyAll 实现生产者消费者模型:

方法一:用五个类来实现,分别为Produce(实现生产过程), Consumer(实现消费过程), ProduceThread(实现生产者线程),ConsumeThread(实现消费者线程),Main等。需要注意的是有两个地方。

① 用while判断当前list是否为空;

② 调用的是object的notifyAll()方法而不是notify()方法。

方法二:用四个类实现,分别为MyService(实现生产和消费过程用synchronized关键字实现同步),ProduceThread(实现生产者线程),ConsumeThread(实现消费者线程),Main。需要注意的也是方法一中的两个地方while和notifyAll()。

LockCondition实现。共有四个类,分别是分别为MyService(实现生产和消费过程,用lock实现线程间同步),ProduceThread(实现生产者线程),ConsumeThread(实现消费者线程),Main。需要注意的也是方法一中的两个地方while和signalAll()。


方法一:

package ProduceConsumer;

import java.util.ArrayList;

public class Produce {
	
	public Object object;
	public ArrayList<Integer> list;//用list存放生产之后的数据,最大容量为1
			
	public Produce(Object object,ArrayList<Integer> list ){
		this.object = object;
		this.list = list;
	}
	
	public void produce() {
		
		synchronized (object) {
			/*只有list为空时才会去进行生产操作*/
			try {
			while(!list.isEmpty()){
					System.out.println("生产者"+Thread.currentThread().getName()+" waiting");
					object.wait();
				} 
			int value = 9999;
			list.add(value);
			System.out.println("生产者"+Thread.currentThread().getName()+" Runnable");
			object.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
		}catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

package ProduceConsumer;

import java.util.ArrayList;

public class Consumer {
	
	public Object object;
	public ArrayList<Integer> list;//用list存放生产之后的数据,最大容量为1
			
	public Consumer(Object object,ArrayList<Integer> list ){
		this.object = object;
		this.list = list;
	}
	
	public void consmer() {
		
		synchronized (object) {
			try {
				/*只有list不为空时才会去进行消费操作*/
				while(list.isEmpty()){
					System.out.println("消费者"+Thread.currentThread().getName()+" waiting");
					object.wait();
				} 
			list.clear();
			System.out.println("消费者"+Thread.currentThread().getName()+" Runnable");
			object.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
			
		}catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	}
	
}


package ProduceConsumer;

public class ProduceThread extends Thread {
	private Produce p;
	public ProduceThread(Produce p){
		this.p = p;
	}
	@Override
	public void run() {
		while (true) {
			p.produce();
		}
	}
}

package ProduceConsumer;

public class ConsumeThread extends Thread {
	private Consumer c;
	public ConsumeThread(Consumer c){
		this.c = c;
	}
	@Override
	public void run() {
		while (true) {
			c.consmer();
		}
	}
}

package ProduceConsumer;

import java.util.ArrayList;

public class Main {
	public static void main(String[] args) {
		Object object = new Object();
		ArrayList<Integer> list = new ArrayList<Integer>();
	
		Produce p = new Produce(object, list);
		Consumer c = new Consumer(object, list);
		
		ProduceThread[] pt = new ProduceThread[2];
		ConsumeThread[] ct = new ConsumeThread[2];
		
		for(int i=0;i<2;i++){
			pt[i] = new ProduceThread(p);
			pt[i].setName("生产者 "+(i+1));
			ct[i] = new ConsumeThread(c);
			ct[i].setName("消费者"+(i+1));
			pt[i].start();
			ct[i].start();
		}
	}
}

方法二:

package ProduceConsumer2;

import java.util.ArrayList;

public class MyService {
	
	public ArrayList<Integer> list = new ArrayList<Integer>();//用list存放生产之后的数据,最大容量为1
	synchronized public void produce() {
			
		try {
			/*只有list为空时才会去进行生产操作*/
			while(!list.isEmpty()){
					System.out.println("生产者"+Thread.currentThread().getName()+" waiting");
					this.wait();
				} 
			int value = 9999;
			list.add(value);
			System.out.println("生产者"+Thread.currentThread().getName()+" Runnable");
			this.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
		}catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
	
	synchronized public void consmer() {
		try {	
			/*只有list不为空时才会去进行消费操作*/
			while(list.isEmpty()){
					System.out.println("消费者"+Thread.currentThread().getName()+" waiting");
					this.wait();
			}
			list.clear();
			System.out.println("消费者"+Thread.currentThread().getName()+" Runnable");
			this.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}

package ProduceConsumer2;

public class ProduceThread extends Thread {
	private MyService p;
	public ProduceThread(MyService p){
		this.p = p;
	}
	@Override
	public void run() {
		while (true) {
			p.produce();
		}
	}
}

package ProduceConsumer2;

public class ConsumeThread extends Thread {
	private MyService c;
	public ConsumeThread(MyService c){
		this.c = c;
	}
	@Override
	public void run() {
		while (true) {
			c.consmer();
		}
	}
}

LockCondition实现

package ConditionProduceConsumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MyService {
	
	private ReentrantLock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	private boolean hasValue = false;
	
	
	 public void produce() {
		lock.lock();
		try {
			/*只有list为空时才会去进行生产操作*/
			while(hasValue == true){
				System.out.println("生产者"+Thread.currentThread().getName()+" waiting");
				condition.await();
			}
			hasValue = true;
			System.out.println("生产者"+Thread.currentThread().getName()+" Runnable");
			condition.signalAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
			
	}
	
	 public void consmer() {
		lock.lock();
		try {
			/*只有list为空时才会去进行生产操作*/
			while(hasValue == false){
				System.out.println("消费者"+Thread.currentThread().getName()+" waiting");
				condition.await();
			}
			hasValue = false;
			System.out.println("消费者"+Thread.currentThread().getName()+" Runnable");
			condition.signalAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	
	}
}

package ConditionProduceConsumer;

public class ProduceThread extends Thread {
	private MyService p;
	public ProduceThread(MyService p){
		this.p = p;
	}
	@Override
	public void run() {
		while (true) {
			p.produce();
		}
	}
}
package ConditionProduceConsumer;

public class ConsumeThread extends Thread {
	private MyService c;
	public ConsumeThread(MyService c){
		this.c = c;
	}
	@Override
	public void run() {
		while (true) {
			c.consmer();
		}
	}
}

package ConditionProduceConsumer;


public class Main {
	public static void main(String[] args) {

		MyService service = new MyService();
		
		ProduceThread[] pt = new ProduceThread[2];
		ConsumeThread[] ct = new ConsumeThread[2];
		
		for(int i=0;i<1;i++){
			pt[i] = new ProduceThread(service);
			pt[i].setName("Condition 生产者 "+(i+1));
			ct[i] = new ConsumeThread(service);
			ct[i].setName("Condition 消费者"+(i+1));
			pt[i].start();
			ct[i].start();
		}
	}
}



  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QSharedMemory是Qt框架中用于在进程之间共享内存的类。要实现生产者消费者模式,可以使用QSharedMemory来作为生产者和消费者之间的共享缓冲区。 下面是一个简单的示例,展示了如何使用QSharedMemory实现生产者消费者模式: ```cpp #include <QtCore/QCoreApplication> #include <QtCore/QSharedMemory> #include <QtCore/QBuffer> #include <QtCore/QDataStream> #include <QtCore/QDebug> // 定义共享内存的大小 #define SHARED_MEMORY_SIZE 1024 // 定义共享内存中的数据结构 struct Data { int value; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建共享内存对象 QSharedMemory sharedMemory("MySharedMemory"); // 创建共享内存并分配大小 if (!sharedMemory.create(SHARED_MEMORY_SIZE)) { qDebug() << "Failed to create shared memory:" << sharedMemory.errorString(); return -1; } // 连接到共享内存 if (!sharedMemory.attach()) { qDebug() << "Failed to attach to shared memory:" << sharedMemory.errorString(); return -1; } // 获取共享内存的指针 void *sharedMemoryPointer = sharedMemory.data(); // 创建数据结构对象 Data *data = new (sharedMemoryPointer) Data; // 生产者循环写入数据到共享内存 for (int i = 0; i < 10; ++i) { data->value = i; // 等待消费者读取数据 while (data->value != -1) { QCoreApplication::processEvents(); } } // 设置终止标志 data->value = -1; // 分离共享内存 sharedMemory.detach(); return a.exec(); } ``` 上述代码中,我们创建了一个QSharedMemory对象并命名为"MySharedMemory"。然后我们使用create()函数创建了一个指定大小的共享内存,如果创建失败,我们打印错误信息并返回。接下来,我们调用attach()函数将当前进程连接到共享内存。通过调用data()函数,我们获取共享内存的指针,并将其转换为我们定义的数据结构Data类型。然后,生产者进程循环向共享内存中写入数据,并通过等待消费者读取数据来进行同步。当生产者完成数据写入后,设置一个终止标志,并通过detach()函数将当前进程与共享内存分离。 请注意,上述代码只实现了生产者部分,你还需要编写一个消费者进程来读取共享内存中的数据。 希望这个示例能帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值