亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java中的多個消費者生產者

Java中的多個消費者生產者

慕哥9229398 2021-08-19 19:17:55
我嘗試為消費者創建 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();            }        }
查看完整描述

1 回答

?
千巷貓影

TA貢獻1829條經驗 獲得超7個贊

更改代碼中出現的iftowhile可以解決問題。


Oracle 網站上的Guarded Blocks 教程中有相關建議,其中說:


注意:始終在測試等待條件的循環內調用 wait。不要假設中斷是針對您正在等待的特定條件,或者條件仍然為真。


(中斷是指從等待中返回,不一定是來自調用 Thread.interrupt 的人的實際中斷。)


關鍵點:


只有當線程在檢查時持有鎖時,它才知道貨物列表的內容。


調用 wait 會放棄鎖,允許其他線程在這個線程處于休眠狀態時取得進展。


一旦線程放棄鎖,它之前對貨物列表狀態所做的任何檢查都不再有效。


一旦線程從等待中返回,它就重新獲得了鎖,但該線程需要重新評估條件檢查,否則它正在處理陳舊的信息。在線程上次檢查條件的時間和當前時間之間可能發生了很多事情。您得到 IllegalArgumentException 是因為當前線程假設在當前線程等待時另一個線程刪除了某些東西。


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) {


            while (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) {


            while (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();

        }

    }


    @Override

    public void run() {

        // TODO Auto-generated method stub

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

            produce(i);

            try {

                Thread.currentThread().sleep(100);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

    }

}


public static void main(String[] args) {

    List<Integer> goods = new ArrayList<>();

    Consumer consumer = new Consumer(goods);

    Producer producer = new Producer(goods);

    Thread consumerWorker1 = new Thread(consumer);

    Thread consumerWorker2 = new Thread(consumer);


    Thread prroducerWorker1 = new Thread(producer);

    Thread prroducerWorker2 = new Thread(producer);


    consumerWorker1.start();

    consumerWorker2.start();

    prroducerWorker1.start();

    prroducerWorker2.start();


    try {

        consumerWorker1.join();

        consumerWorker2.join();

        prroducerWorker1.join();

        prroducerWorker2.join();

    } catch (InterruptedException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

    }


    System.out.println("Job completed >>>>");

}


}

代碼現在成功完成,輸出如下:


C:\>java com.threading.TestConsumerProducer2

Thread-2>>> producing >> 0

Thread-1 >>>> consuming >>>0

Thread-3>>> producing >> 0

Thread-0 >>>> consuming >>>0

Thread-2>>> producing >> 1

Thread-3>>> producing >> 1

Thread-0 >>>> consuming >>>1

Thread-1 >>>> consuming >>>1

Thread-2>>> producing >> 2

Thread-3>>> producing >> 2

Thread-0 >>>> consuming >>>2

Thread-1 >>>> consuming >>>2

Thread-2>>> producing >> 3

Thread-0 >>>> consuming >>>3

Thread-3>>> producing >> 3

Thread-1 >>>> consuming >>>3

Thread-2>>> producing >> 4

Thread-0 >>>> consuming >>>4

Thread-3>>> producing >> 4

Thread-1 >>>> consuming >>>4

Thread-2>>> producing >> 5

Thread-0 >>>> consuming >>>5

Thread-3>>> producing >> 5

Thread-1 >>>> consuming >>>5

Thread-2>>> producing >> 6

Thread-0 >>>> consuming >>>6

Thread-3>>> producing >> 6

Thread-1 >>>> consuming >>>6

Thread-2>>> producing >> 7

Thread-0 >>>> consuming >>>7

Thread-3>>> producing >> 7

Thread-1 >>>> consuming >>>7

Thread-2>>> producing >> 8

Thread-0 >>>> consuming >>>8

Thread-3>>> producing >> 8

Thread-1 >>>> consuming >>>8

Thread-2>>> producing >> 9

Thread-0 >>>> consuming >>>9

Thread-3>>> producing >> 9

Thread-1 >>>> consuming >>>9

Job completed >>>>


查看完整回答
反對 回復 2021-08-19
  • 1 回答
  • 0 關注
  • 230 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號