Java生產(chǎn)者/消費者模型的一種實現(xiàn)

本文主要介紹java中生產(chǎn)者/消費者模式的實現(xiàn),對java線程鎖機制的一次深入理解。

生產(chǎn)者/消費者模型

生產(chǎn)者/消費者模型要保證,同一個資源在同一時間節(jié)點下只能被最多一個線程訪問,這個在java中用鎖就很容易實現(xiàn)。

下面的例子就是模擬多個生產(chǎn)者生產(chǎn),多個消費者消費的demo

//抽象生產(chǎn)者
public abstract class AbstractProducer implements Runnable {

    abstract void produce() throws InterruptedException;

    @Override
    public void run() {
        try {
            while (true) {
                produce();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

//抽象消費者
public abstract class AbstractConsumer implements Runnable {

    abstract void consume() throws InterruptedException;

    @Override
    public void run() {
        try {
            while (true) {
                consume();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class ConsumerAndProducerDemo {

    private static final AtomicInteger ATOMIC_INTEGER = new AtomicInteger();

    private static final ReentrantLock LOCK = new ReentrantLock();

    private static final Condition CONDITION = LOCK.newCondition();

    private static final Queue<Product> PRODUCTS = new LinkedList<>();

    private static final int SIZE = 4;

    public static class Product {
        int id;

        Product(int id) {
            this.id = id;
        }
    }

    //實現(xiàn)消費者
    private static class Consumer extends AbstractConsumer {

        @Override
        void consume() throws InterruptedException {
            try {
                LOCK.lock();
                while (PRODUCTS.isEmpty()) {
                    CONDITION.await();
                }

                Product product = PRODUCTS.poll();
                Thread.sleep((long) (500 + Math.random() * 1000));
                System.out.println(" consume product " + product.id);
                CONDITION.signalAll();
            } finally {
                LOCK.unlock();
            }
        }
    }

    //實現(xiàn)生產(chǎn)者
    private static class Producer extends AbstractProducer {

        @Override
        void produce() throws InterruptedException {
            try {
                LOCK.lock();
                while (PRODUCTS.size() >= SIZE) {
                    CONDITION.await();
                }

                Thread.sleep(1000);
                Product product = new Product(ATOMIC_INTEGER.incrementAndGet());
                PRODUCTS.add(product);
                System.out.println("produce product " + product.id);

                CONDITION.signalAll();
            } finally {
                LOCK.unlock();
            }
        }
    }

    public static void main(String[] args) {
        for (int index = 0; index < 2; index++) {
            new Thread(new Producer()).start();
        }

        for (int index = 0; index < 3; index++) {
            new Thread(new Consumer()).start();
        }
    }
}

上面的demo這么實現(xiàn)

  1. 啟動多個線程模擬多個生產(chǎn)者和多個消費者
  2. 同時使用了queue用來緩存產(chǎn)品
  3. 當緩存區(qū)沒滿時生產(chǎn)者生產(chǎn)
  4. 當緩沖區(qū)滿時消費者開始消費

線程之間的同步,這里使用了ReentrantLock,ReentrantLock在之前的博客中有介紹過,當然也可以使用Object自帶的wait()等方法,實現(xiàn)同步這里就不在修改demo另行實現(xiàn)了。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,030評論 25 709
  • 一是文本觀。解讀文本不深,挖掘教材不透,缺乏自己的主張;二是目標觀。目標不夠具體,不可測量,不能體現(xiàn)學習成果;三是...
    晴晴老師閱讀 264評論 0 0
  • 線程的狀態(tài) 線程的幾種狀態(tài) 1.新建線程之后,開啟start的那一瞬間:線程對象會進入可調(diào)度線程池中 2.star...
    Mario_ZJ閱讀 480評論 0 0
  • 小時候,我不喜歡讀書。每到假期父母站在身邊,我托著頭,疲倦地啃著千篇一律的文字,那時還不知道讀書的幸福。而這個假期...
    女王冊冊閱讀 254評論 0 2

友情鏈接更多精彩內(nèi)容