Java多線程併發採用BlockingQueue阻塞隊列實現生產者和消費者模式

1、BlockingQueue簡介

BlockingQueue 通常用於一個線程生產對象,而另外一個線程消費這些對象的場景。
一個線程往裏邊放,另外一個線程從裏邊取的一個 BlockingQueue。
一個線程將會持續生產新對象並將其插入到隊列之中,直到隊列達到它所能容納的臨界點。也就是說,它是有限的。如果該阻塞隊列到達了其臨界點,負責生產的線程將會在往裏邊插入新對象時發生阻塞。它會一直處於阻塞之中,直到負責消費的線程從隊列中拿走一個對象。
負責消費的線程將會一直從該阻塞隊列中拿出對象。如果消費線程嘗試去從一個空的隊列中提取對象的話,這個消費線程將會處於阻塞之中,直到一個生產線程把一個對象丟進隊列。

2、BlockingQueue的放入數據put()方法簡介

put()方法將指定元素插入此隊列中,將等待可用的空間.通俗點說就是某個值>maxSize 時候,就阻塞,直到能夠有足夠空間插入元素。

3、BlockingQueue的獲取數據take()方法簡介

take()方法獲取並移除此隊列的頭部,說通俗點就是拿出來並且刪掉,在元素變得可用之前一直等待 。queue的長度 == 0 的時候,一直阻塞,直到生產者又放入了新的數據。

4、生產者代碼

package QueueTest;

import java.util.concurrent.BlockingQueue;
/**
 * 生產者類
 * @author 小軒
 *
 */
public class ProducterQueue implements Runnable {
	private final BlockingQueue proQueue;
	
	public ProducterQueue(BlockingQueue proQueue) {
		// TODO Auto-generated constructor stub
		this.proQueue = proQueue;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 10; i++) {
			try {
				//放入10瓶可樂 編號爲0到9 也就是1-10 i初始單位爲0
				//put()方法將指定元素插入此隊列中,將等待可用的空間.通俗點說就是>maxSize 時候,阻塞,直到能夠有空間插入元素
				System.out.println("生產的可樂編號爲:"+i);
				proQueue.put(i);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}

5、消費者代碼

package QueueTest;

import java.util.concurrent.BlockingQueue;
/**
 * 消費者類
 * @author 小軒
 *
 */
public class ConsumerQueue implements Runnable {
	
	private final BlockingQueue conQueue;
	
	public ConsumerQueue(BlockingQueue conQueue) {
		// TODO Auto-generated constructor stub
		this.conQueue = conQueue;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 10; i++) {
			try {
				//take()方法獲取並移除此隊列的頭部,說通俗點就是拿出來並且刪掉,在元素變得可用之前一直等待 。queue的長度 == 0 的時候,一直阻塞,直到生產者又放入了新的數據。
				System.out.println("**************消費者消費的可樂編號爲:"+conQueue.take());
				//休眠一下方便看的更清楚
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

}

6、主程序入口類

package QueueTest;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * 主程序入口類
 * @author 小軒
 *
 */
public class test {
	public static void main(String[] args) {
		//自定義大小爲5一個盒子 這裏需要注意0到5是六次
		BlockingQueue publicQueue = new LinkedBlockingQueue(5);
		//實例化生產者
		ProducterQueue pro = new ProducterQueue(publicQueue);
		//實例化消費者
		ConsumerQueue con = new ConsumerQueue(publicQueue);
		//實例化生產者線程
		Thread t1 = new Thread(pro);
		//實例化消費者線程
		Thread t2 = new Thread(con);
		//啓動兩個線程
		t1.start();
		t2.start();
	}

}

7、遇到困難可以評論(有信必回)小軒微信17382121839。

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