用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()
后再次检查条件。