Java中的多个消费者生产者

我尝试为消费者创建 2 个线程,为生产者创建 2 个线程。所有 4 个线程都在与一种资源竞争。其中两个试图从资源中消费,其中两个试图生产。


下面是代码


package com.threading;


import java.util.ArrayList;

import java.util.List;


public class TestConsumerProducer2 {


    protected static int maxSize = 2;


    static class Consumer implements Runnable {

        List<Integer> goods;


        public Consumer(List<Integer> goods) {

            this.goods = goods;

        }


        public void consume() {

            synchronized (goods) {


                if (goods.size() <= 0) {

                    try {

                        goods.wait();

                    } catch (InterruptedException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }

                System.out.println(Thread.currentThread().getName() + " >>>> consuming >>>" + goods.remove(0));

                goods.notifyAll();

            }

        }


        @Override

        public void run() {

            for (int i = 0; i < 10; i++) {

                consume();

                try {

                    Thread.currentThread().sleep(100);

                } catch (InterruptedException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

                }

            }

        }

    }


    static class Producer implements Runnable {

        List<Integer> goods;


        public Producer(List<Integer> goods) {

            this.goods = goods;

        }


        public void produce(int i) {

            synchronized (goods) {


                if (goods.size() >= maxSize) {

                    try {

                        goods.wait();

                    } catch (InterruptedException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }

                System.out.println(Thread.currentThread().getName() + ">>> producing >> " + i);

                goods.add(i);

                goods.notifyAll();

            }

        }



慕哥9229398
浏览 208回答 1
1回答

千巷猫影

更改代码中出现的iftowhile可以解决问题。Oracle 网站上的Guarded Blocks 教程中有相关建议,其中说:注意:始终在测试等待条件的循环内调用 wait。不要假设中断是针对您正在等待的特定条件,或者条件仍然为真。(中断是指从等待中返回,不一定是来自调用 Thread.interrupt 的人的实际中断。)关键点:只有当线程在检查时持有锁时,它才知道货物列表的内容。调用 wait 会放弃锁,允许其他线程在这个线程处于休眠状态时取得进展。一旦线程放弃锁,它之前对货物列表状态所做的任何检查都不再有效。一旦线程从等待中返回,它就重新获得了锁,但该线程需要重新评估条件检查,否则它正在处理陈旧的信息。在线程上次检查条件的时间和当前时间之间可能发生了很多事情。您得到 IllegalArgumentException 是因为当前线程假设在当前线程等待时另一个线程删除了某些东西。package com.threading;import java.util.ArrayList;&nbsp;import java.util.List;public class TestConsumerProducer2 {protected static int maxSize = 2;static class Consumer implements Runnable {&nbsp; &nbsp; List<Integer> goods;&nbsp; &nbsp; public Consumer(List<Integer> goods) {&nbsp; &nbsp; &nbsp; &nbsp; this.goods = goods;&nbsp; &nbsp; }&nbsp; &nbsp; public void consume() {&nbsp; &nbsp; &nbsp; &nbsp; synchronized (goods) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (goods.size() <= 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goods.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Thread.currentThread().getName() + " >>>> consuming >>>" + goods.remove(0));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goods.notifyAll();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 10; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; consume();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.currentThread().sleep(100);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}static class Producer implements Runnable {&nbsp; &nbsp; List<Integer> goods;&nbsp; &nbsp; public Producer(List<Integer> goods) {&nbsp; &nbsp; &nbsp; &nbsp; this.goods = goods;&nbsp; &nbsp; }&nbsp; &nbsp; public void produce(int i) {&nbsp; &nbsp; &nbsp; &nbsp; synchronized (goods) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (goods.size() >= maxSize) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goods.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Thread.currentThread().getName() + ">>> producing >> " + i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goods.add(i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goods.notifyAll();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated method stub&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 10; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; produce(i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.currentThread().sleep(100);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}public static void main(String[] args) {&nbsp; &nbsp; List<Integer> goods = new ArrayList<>();&nbsp; &nbsp; Consumer consumer = new Consumer(goods);&nbsp; &nbsp; Producer producer = new Producer(goods);&nbsp; &nbsp; Thread consumerWorker1 = new Thread(consumer);&nbsp; &nbsp; Thread consumerWorker2 = new Thread(consumer);&nbsp; &nbsp; Thread prroducerWorker1 = new Thread(producer);&nbsp; &nbsp; Thread prroducerWorker2 = new Thread(producer);&nbsp; &nbsp; consumerWorker1.start();&nbsp; &nbsp; consumerWorker2.start();&nbsp; &nbsp; prroducerWorker1.start();&nbsp; &nbsp; prroducerWorker2.start();&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; consumerWorker1.join();&nbsp; &nbsp; &nbsp; &nbsp; consumerWorker2.join();&nbsp; &nbsp; &nbsp; &nbsp; prroducerWorker1.join();&nbsp; &nbsp; &nbsp; &nbsp; prroducerWorker2.join();&nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; }&nbsp; &nbsp; System.out.println("Job completed >>>>");}}代码现在成功完成,输出如下:C:\>java com.threading.TestConsumerProducer2Thread-2>>> producing >> 0Thread-1 >>>> consuming >>>0Thread-3>>> producing >> 0Thread-0 >>>> consuming >>>0Thread-2>>> producing >> 1Thread-3>>> producing >> 1Thread-0 >>>> consuming >>>1Thread-1 >>>> consuming >>>1Thread-2>>> producing >> 2Thread-3>>> producing >> 2Thread-0 >>>> consuming >>>2Thread-1 >>>> consuming >>>2Thread-2>>> producing >> 3Thread-0 >>>> consuming >>>3Thread-3>>> producing >> 3Thread-1 >>>> consuming >>>3Thread-2>>> producing >> 4Thread-0 >>>> consuming >>>4Thread-3>>> producing >> 4Thread-1 >>>> consuming >>>4Thread-2>>> producing >> 5Thread-0 >>>> consuming >>>5Thread-3>>> producing >> 5Thread-1 >>>> consuming >>>5Thread-2>>> producing >> 6Thread-0 >>>> consuming >>>6Thread-3>>> producing >> 6Thread-1 >>>> consuming >>>6Thread-2>>> producing >> 7Thread-0 >>>> consuming >>>7Thread-3>>> producing >> 7Thread-1 >>>> consuming >>>7Thread-2>>> producing >> 8Thread-0 >>>> consuming >>>8Thread-3>>> producing >> 8Thread-1 >>>> consuming >>>8Thread-2>>> producing >> 9Thread-0 >>>> consuming >>>9Thread-3>>> producing >> 9Thread-1 >>>> consuming >>>9Job completed >>>>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java