java使用阻塞隊列(BlockingQueue)來控制線程通信

當生產者試圖向BlockingQueue中放入元素時,如果該隊列已滿,則該線程被阻塞;當消費者試圖從BlockingQueue取出元素時,如果該隊列爲空,則該線程被阻塞。


package bloc;

import java.util.concurrent.*;

public class BlockingQueueTest
{
	public static void main(String[] args)
		throws Exception
	{
		// 定義一個長度爲2的阻塞隊列
		BlockingQueue<String> bq = new ArrayBlockingQueue<>(2);
		bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
		bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
		bq.put("Java"); // ① 阻塞線程。
	}
}

package bloc;

import java.util.concurrent.*;

class Producer extends Thread
{
	private BlockingQueue<String> bq;
	public Producer(BlockingQueue<String> bq)
	{
		this.bq = bq;
	}
	public void run()
	{
		String[] strArr = new String[]
		{
			"Java",
			"Struts",
			"Spring"
		};
		for (int i = 0 ; i < 999999999 ; i++ )
		{
			System.out.println(getName() + "生產者準備生產集合元素!");
			try
			{
				Thread.sleep(200);
				// 嘗試放入元素,如果隊列已滿,線程被阻塞
				bq.put(strArr[i % 3]);
			}
			catch (Exception ex){ex.printStackTrace();}
			System.out.println(getName() + "生產完成:" + bq);
		}
	}
}
class Consumer extends Thread
{
	private BlockingQueue<String> bq;
	public Consumer(BlockingQueue<String> bq)
	{
		this.bq = bq;
	}
	public void run()
	{
		while(true)
		{
			System.out.println(getName() + "消費者準備消費集合元素!");
			try
			{
				Thread.sleep(200);
				// 嘗試取出元素,如果隊列已空,線程被阻塞
				bq.take();
			}
			catch (Exception ex){ex.printStackTrace();}
			System.out.println(getName() + "消費完成:" + bq);
		}
	}
}
public class BlockingQueueTest2
{
	public static void main(String[] args)
	{
		// 創建一個容量爲1的BlockingQueue
		BlockingQueue<String> bq = new ArrayBlockingQueue<>(1);
		// 啓動3條生產者線程
		new Producer(bq).start();
		new Producer(bq).start();
		new Producer(bq).start();
		// 啓動一條消費者線程
		new Consumer(bq).start();
	}
}

ArrayBlockingQueue

   一個由數組支持的有限阻塞隊列(其大小在創建的時候就被確定,並且不能在修改)。此隊列裏存儲的元素順序是FIFO(first-in-first-out),是一個很標準的普通隊列,也是我們最常使用到的阻塞隊列。其頭部的元素是在隊列帶的時間最長,尾部元素在隊列中呆的時間最短,新來的元素是插在尾部的,而當隊列獲取元素時是從頭部獲取的。如果試圖將一個元素put到一個full狀態的隊列,這個操作就會被阻塞,直到隊列有空位置。如果從一個empty隊列獲取新的元素同樣也會被阻塞,知道有元素可獲取。


DelayQueue

    此隊列是一個無界限的隊列,只有當他的元素在隊列中超過規定時間了他纔可以被取出來,其頭部是超期時間最長的元素,尾部就是超期最短(或還未過期)的元素。如果還沒有過期的元素,那麼就不存在頭部了,將直接返當回null,他的隊列調用了元素的getDelay()方法返回的值小於或等於0就表示過期了。

    這個隊列不是所有的元素都可以放進去的,必須是實現了Delayed接口的類對象纔可以放進去,否則就會報類型轉換異常,


LinkedBlockingQueue

    是一個基於連接節點的任意大小容量的隊列,這個隊列的順序是FIFO,其頭部是存入隊列最早的元素,尾部是存入隊列最晚的元素,每次都是講元素插入尾部,從頭部取出元素。LinkedBlockingQueue:比ArrayBlockingQueue有更大的吞吐量,但是在併發的情況下其性能是不可預測的。

http://blog.csdn.net/u012481172/article/details/50469690  參考鏈接

發佈了39 篇原創文章 · 獲贊 9 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章