用Java实现生产者消费者
这是一个实现生产者消费者模式的家庭作业。下面的实现有什么问题。我在谷歌上搜索过各种实现,但我无法理解我的实现出了什么问题 我有一个共享队列 我在同一个锁上同步生产者和消费者 实施 共享队列:用Java实现生产者消费者,java,multithreading,concurrency,producer-consumer,Java,Multithreading,Concurrency,Producer Consumer,这是一个实现生产者消费者模式的家庭作业。下面的实现有什么问题。我在谷歌上搜索过各种实现,但我无法理解我的实现出了什么问题 我有一个共享队列 我在同一个锁上同步生产者和消费者 实施 共享队列: class SharedQueue{ public static Queue<Integer> queue = new LinkedList<Integer>(); } //The producer thread class Producer implements
class SharedQueue{
public static Queue<Integer> queue = new LinkedList<Integer>();
}
//The producer thread
class Producer implements Runnable{
public void run()
{
synchronized (SharedQueue.queue)
{
if(SharedQueue.queue.size() >=5)
{
try {
SharedQueue.queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Random r = new Random();
int x = r.nextInt(10);
System.out.println("Inside Producer" + x);
SharedQueue.queue.offer(x);
SharedQueue.queue.notify();
}
}
}
class Consumer implements Runnable{
public void run()
{
synchronized (SharedQueue.queue)
{
if(SharedQueue.queue.size() == 0)
{
try {
SharedQueue.queue.wait();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
int k = SharedQueue.queue.remove();
System.out.println("Inside consumer" + k);
}
}
}
消费者线程:
class SharedQueue{
public static Queue<Integer> queue = new LinkedList<Integer>();
}
//The producer thread
class Producer implements Runnable{
public void run()
{
synchronized (SharedQueue.queue)
{
if(SharedQueue.queue.size() >=5)
{
try {
SharedQueue.queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Random r = new Random();
int x = r.nextInt(10);
System.out.println("Inside Producer" + x);
SharedQueue.queue.offer(x);
SharedQueue.queue.notify();
}
}
}
class Consumer implements Runnable{
public void run()
{
synchronized (SharedQueue.queue)
{
if(SharedQueue.queue.size() == 0)
{
try {
SharedQueue.queue.wait();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
int k = SharedQueue.queue.remove();
System.out.println("Inside consumer" + k);
}
}
}
主程序
public class ProducerConsumerTest {
public static void main(String[] args)
{
Thread p = new Thread(new Producer());
Thread q = new Thread(new Consumer());
p.start();
q.start();
}
}
尝试替换:
if(SharedQueue.queue.size() >= 5)
与:
这是:
if(SharedQueue.queue.size() == 0)
与:
只要在调用
notify()
后重新检查条件,我假设您希望这是生产者-消费者的无休止循环。在Eng.Fouad的顶部
更改,环绕两个同步块,包括:
while (true)
并在消费者中添加通知
int k = SharedQueue.queue.remove();
// make the producer active again
SharedQueue.queue.notify();
System.out.println("Inside consumer " + k);
实现生产者-消费者问题的简单方法是使用信号量
public class Semaphore {
int value;
public Semaphore(int intialValue) {
this.value = intialValue;
}
public synchronized void p() {
while (value <= 0) {
try {
this.wait();
} catch (InterruptedException e) {
}
}
value = value - 1;
}
public synchronized void v() {
value = value + 1;
this.notify();
}
}
public class ProducerConsumerUsingSemaphore {
private static final int SIZE = 10;
public static void main(String[] args) {
Semaphore full = new Semaphore(0);
Semaphore empty = new Semaphore(SIZE);
Semaphore mutex = new Semaphore(1);
Vector<Integer> sQueue = new Vector<Integer>();
Thread producerThread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5000; i++) {
empty.p();
mutex.p();
System.out.println(Thread.currentThread().getName() + " is trying to insert item " + i);
sQueue.add(i);
mutex.v();
full.v();
}
}
});
Thread consumerThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
full.p();
mutex.p();
System.out.println(Thread.currentThread().getName() + " consuming item " + sQueue.remove(0));
mutex.v();
empty.v();
}
}
});
producerThread.setName("Producer");
consumerThread.setName("Consumer");
consumerThread.start();
producerThread.start();
}
}
公共类信号量{
int值;
公共信号量(int初始值){
this.value=初始值;
}
公共同步void p(){
虽然(值您可以使用ConcurrentLinkedQueue来管理生产者和消费者的共享队列。您可以使用ConcurrentHashMap>collection,这将帮助生产者并发生产,消费者也可以并发消费,并将生产者生成的密钥保存在另一个集合对象中,消费者可以在其中找到其密钥d从ConcurrentHashMap>中消费它只需使用我的毒药模式即可:
public class ProducerAndConsumer {
public static void main(String a[]) {
Resource resource = new Resource();
Producer producer = new Producer(resource);
Consumer consumer = new Consumer(resource);
producer.start();
consumer.start();
}
}
class Resource {
private int item = 0;
boolean flag = true;
public void getItem() {
while (true) {
synchronized (this) {
if (!flag) {
try {
System.out.println("Consumer consume item :" + item);
flag = true;
Thread.sleep(10);
notify();
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public void setItem() {
while (true) {
synchronized (this) {
if (flag) {
try {
item++;
System.out.println("Producer creating item :" + item);
flag = false;
Thread.sleep(10);
notify();
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
class Producer extends Thread {
Resource resource = null;
Producer(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
resource.setItem();
}
}
class Consumer extends Thread {
Resource resource = null;
Consumer(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
resource.getItem();
}
}
public sealed interface BaseMessage {
final class ValidMessage<T> implements BaseMessage {
@Nonnull
private final T value;
public ValidMessage(@Nonnull T value) {
this.value = value;
}
@Nonnull
public T getValue() {
return value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ValidMessage<?> that = (ValidMessage<?>) o;
return value.equals(that.value);
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return "ValidMessage{value=%s}".formatted(value);
}
}
final class PoisonedMessage implements BaseMessage {
public static final PoisonedMessage INSTANCE = new PoisonedMessage();
private PoisonedMessage() {
}
@Override
public String toString() {
return "PoisonedMessage{}";
}
}
}
public class Producer implements Callable<Void> {
@Nonnull
private final BlockingQueue<BaseMessage> messages;
Producer(@Nonnull BlockingQueue<BaseMessage> messages) {
this.messages = messages;
}
@Override
public Void call() throws Exception {
messages.put(new BaseMessage.ValidMessage<>(1));
messages.put(new BaseMessage.ValidMessage<>(2));
messages.put(new BaseMessage.ValidMessage<>(3));
messages.put(BaseMessage.PoisonedMessage.INSTANCE);
return null;
}
}
public class Consumer implements Callable<Void> {
@Nonnull
private final BlockingQueue<BaseMessage> messages;
private final int maxPoisons;
public Consumer(@Nonnull BlockingQueue<BaseMessage> messages, int maxPoisons) {
this.messages = messages;
this.maxPoisons = maxPoisons;
}
@Override
public Void call() throws Exception {
int poisonsReceived = 0;
while (poisonsReceived < maxPoisons && !Thread.currentThread().isInterrupted()) {
BaseMessage message = messages.take();
if (message instanceof BaseMessage.ValidMessage<?> vm) {
Integer value = (Integer) vm.getValue();
System.out.println(value);
} else if (message instanceof BaseMessage.PoisonedMessage) {
++poisonsReceived;
} else {
throw new IllegalArgumentException("Invalid BaseMessage type: " + message);
}
}
return null;
}
}
公共密封接口基本消息{
最后一个类ValidMessage实现BaseMessage{
@非空
私人最终T值;
公共有效消息(@Nonnull T值){
这个值=值;
}
@非空
公共T getValue(){
返回值;
}
@凌驾
公共布尔等于(对象o){
如果(this==o)返回true;
如果(o==null | | getClass()!=o.getClass())返回false;
ValidMessage that=(ValidMessage)o;
返回值.equals(即.value);
}
@凌驾
公共int hashCode(){
返回Objects.hash(值);
}
@凌驾
公共字符串toString(){
返回“ValidMessage{value=%s}”。格式化(值);
}
}
最后一个类TownedMessage实现BaseMessage{
public static final-毒物消息实例=new-毒物消息();
私人中毒信息(){
}
@凌驾
公共字符串toString(){
返回“中毒消息{}”;
}
}
}
公共类生产者实现了可调用{
@非空
私有最终阻塞队列消息;
生产者(@Nonnull BlockingQueue消息){
this.messages=消息;
}
@凌驾
public Void call()引发异常{
messages.put(新的BaseMessage.ValidMessage(1));
messages.put(新的BaseMessage.ValidMessage(2));
messages.put(新的BaseMessage.ValidMessage(3));
messages.put(BaseMessage.毒物消息.INSTANCE);
返回null;
}
}
公共类使用者实现了可调用{
@非空
私有最终阻塞队列消息;
私人毒药;
公共消费者(@Nonnull BlockingQueue消息,int-max毒物){
this.messages=消息;
this.max毒物=max毒物;
}
@凌驾
public Void call()引发异常{
int毒物接收=0;
而(毒物接收
我不知道。出了什么问题?出了什么问题?作为一般规则,更喜欢java.util.concurrent
中的实用程序,而不是使用wait
和notify
(有效java,第69项)进行编码。如果我们用while(true){}包围同步块,它还需要我们使用while(SharedQueue.queue.size()>=5)与if(SharedQueue.queue.size()>=5)?@user2434 Yes不同,内部while循环用于在另一个线程调用notify()
后再次检查条件。