Java 阻塞隊列實現生產者和消費者場景

1. 阻塞隊列

阻塞隊列(BlockingQueue)是一個支持兩個附加操作的隊列。這兩個附加的操作是:

  • 在隊列爲空時,獲取元素的線程會等待隊列變爲非空。
  • 當隊列滿時,存儲元素的線程會等待隊列可用。

當阻塞隊列滿時,如果生產者線程使用put方法向隊列中添加元素,隊列會一直阻塞生產者線程,直到拿到數據,或者響應中斷退出。當隊列空時,消費者使用take方法從隊列中獲取元素,隊列也會阻塞消費者線程,直到隊列可用。

2. 阻塞隊列實現生產者和消費者實例

生產者線程,ProducerThread.java:

import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 生產者線程
 * @author syrdbt
 * @date 2020-02-26
 */
public class ProducerThread implements Runnable{

    private LinkedBlockingQueue blockingQueue;

    public ProducerThread(LinkedBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        Random random = new Random();
        while (true) {
            try {
                this.produce(random.nextInt(5));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void produce(int productNumber) throws InterruptedException {
        TimeUnit.SECONDS.sleep(productNumber);
        blockingQueue.put(productNumber);
        System.out.println("【生產者】生產了" + productNumber + "號產品,花費了" + productNumber + "秒,成功的添加"
                + productNumber + "產品到了隊列中");
    }
}

消費者線程,ConsumerThread.java:

/**
 * 消費者線程
 * @author syrdbt
 * @date 2020-02-26
 */
public class ConsumerThread implements Runnable{

    private LinkedBlockingQueue blockingQueue;

    public ConsumerThread(LinkedBlockingQueue blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        Random random = new Random();
        while (true) {
            try {
                this.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void consume() throws InterruptedException {
        int productNumber = (int) blockingQueue.take();
        TimeUnit.SECONDS.sleep(productNumber);
        System.out.println("【消費者】消費了" + productNumber + "號產品,花費了" +
                productNumber + "秒,成功的從隊列中取出" + productNumber + "號產品");
    }
}

測試程序,Main.java:

import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author syrdbt
 * @date 2020-02-26
 */
public class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue blockingQueue = new LinkedBlockingQueue();
        Thread producerThread = new Thread(new ProducerThread(blockingQueue));
        Thread consumerThread = new Thread(new ConsumerThread(blockingQueue));
        producerThread.start();
        consumerThread.start();
    }
}

測試程序運行截圖如下:
在這裏插入圖片描述

參考文獻

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章