1. 程式人生 > >生產者-消費者模式

生產者-消費者模式

結果 [] del create val emp nbsp 處理 priority

生產者-消費者模式

  

1. 阻塞隊列  

  生產者消費者模式中,一般采用阻塞隊列來實現。阻塞隊列(BlockingQueue)是一個支持兩個附加操作的隊列。這兩個附加的操作是:在隊列為空時,獲取元素的線程會等待隊列變為非空。當隊列滿時,存儲元素的線程會等待隊列可用。

2. 阻塞隊列的運用

  當隊列中沒有數據的情況下,消費者端的所有線程都會被自動阻塞(掛起),直到有數據放入隊列。

  當隊列中填滿數據的情況下,生產者端的所有線程都會被自動阻塞(掛起),直到隊列中有空的位置,線程被自動喚醒。

  阻塞隊列中提供了四種處理方法

  技術分享圖片

  JDK7提供了7個阻塞隊列。分別是

  1)ArrayBlockingQueue :一個由數組結構組成的有界阻塞隊列。

  2)LinkedBlockingQueue :一個由鏈表結構組成的有界阻塞隊列。

  3)PriorityBlockingQueue :一個支持優先級排序的無界阻塞隊列。

  4)DelayQueue:一個使用優先級隊列實現的無界阻塞隊列。

  5)SynchronousQueue:一個不存儲元素的阻塞隊列。

  6)LinkedTransferQueue:一個由鏈表結構組成的無界阻塞隊列。

  7)LinkedBlockingDeque:一個由鏈表結構組成的雙向阻塞隊列。

3. 生產者-消費者的代碼實現

生產者:

package com.commonCode.producerConsumer;

import java.util.concurrent.BlockingQueue; /** * Created by Demrystv. */ public class Producer implements Runnable { BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this.queue = queue; } @Override public void run() { try
{ String temp = "A Product, 生產線程:" + Thread.currentThread().getName(); System.out.println("I have made a product:" + Thread.currentThread().getName()); queue.put(temp);//如果對壘是滿的話,會阻塞當前線程 } catch (InterruptedException e) { e.printStackTrace(); } } }

消費者:

package com.commonCode.producerConsumer;

import java.util.concurrent.BlockingQueue;

/**
 * Created by Demrystv.
 */
public class Consumer implements Runnable {

    BlockingQueue<String> queue;

    public Consumer(BlockingQueue<String> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            String temp = queue.take();//如果隊列為空,就會阻塞線程
            System.out.println(temp);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

測試類:

package com.commonCode.producerConsumer;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * Created by Demrystv.
 */
public class test {

    public static void main(String[] args) {
        BlockingQueue<String> queue = new LinkedBlockingDeque<String>(2);
        //不設置的話,默認值為Integer.MAX_VALUE

        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);
        for (int i = 0; i < 5; i++) {
            new Thread(producer, "Producer" + (i + 1)).start();
            new Thread(consumer, "Consumer" + (i + 1)).start();
        }
    }
}

執行結果:

技術分享圖片

生產者-消費者模式