版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/woshimike/article/details/53762148
BlockingQueue 使用方法筆記
本例介紹一個特殊的隊列:BlockingQueue,它是阻塞式隊列,如果從BlockingQueue中讀數據,此時BlockingQueue爲空這個操作會被阻塞進入等待狀態,直到BlockingQueue寫入元素會被喚醒,同理如果BlockingQueue是滿的,任何寫入操作 會被阻塞進入等待狀態,直到BlockingQueue裏面有空間才被喚醒。
一、BlockingQueue常用方法:
1)add(E e):
添加元素,如果BlockingQueue可以容納,則返回true,否則報異常
2)offer(E e):
添加元素,如果BlockingQueue可以容納,則返回true,否則返回false.
3)put(E e):
添加元素,如果BlockQueue沒有空間,則調用此方法的線程被阻斷直到BlockingQueue裏面有空間再繼續.
4)poll(long timeout, TimeUnit timeUnit):
取走BlockingQueue裏排在首位的對象,若不能立即取出,則可以等timeout參數規定的時間,取不到時返回null
5)take():
取走BlockingQueue裏排在首位的對象,若BlockingQueue爲空,阻斷進入等待狀態直到Blocking有新的對象被加入爲止
二、BlockingQueue常用實現類
1)ArrayBlockingQueue:
有界的先入先出順序隊列,構造方法確定隊列的大小.
2)LinkedBlockingQueue:
無界的先入先出順序隊列,構造方法提供兩種,一種初始化隊列大小,隊列即有界;第二種默認構造方法,隊列無界(有界即 Integer.MAX_VALUE)
4)SynchronousQueue:
特殊的BlockingQueue,沒有空間的隊列,即必須有取的方法阻塞在這裏的時候才能放入元素。
3)PriorityBlockingQueue:
支持優先級的阻塞隊列 ,存入對象必須實現Comparator接口 (需要注意的是 隊列不是在加入元素的時候進行排序,而是取出的時候,根據Comparator來決定優先級最高的)。
如下是阻塞隊列的簡單實現:
package com.lyq.jsoup.MyQueue;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class MyQueue {
private List<Object> mq = new LinkedList<>();
private AtomicInteger couter = new AtomicInteger();
private int maxSize = 20;
private int minSize = 0;
private Object lock = new Object();
public MyQueue(int minSize,int maxSize){
this.minSize = minSize;
this.maxSize = maxSize;
}
public Object take(){
Object ret = null;
synchronized (lock){
if (this.couter.get() == minSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ret = mq.remove(0);
System.out.println("take:"+ret);
couter.decrementAndGet();
lock.notify();
}
return ret;
}
public void put(Object obj){
synchronized (lock){
if (this.couter.get() == maxSize){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mq.add(obj);
System.out.println("put:"+obj);
couter.incrementAndGet();
lock.notify();
}
}
@Override
public String toString() {
return "MyQueue{" +
"mq=" + mq +
", couter=" + couter +
", max=" + maxSize +
", min=" + minSize +
", lock=" + lock +
'}';
}
public static void main(String[] args){
MyQueue mq = new MyQueue(3,5);
mq.put("a");
mq.put("b");
mq.put("c");
mq.put("d");
mq.put("e");
new Thread(new Runnable() {
@Override
public void run() {
mq.put("f");
mq.put("g");
mq.put("h");
}
},"t1").start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
mq.take();
mq.take();
mq.take();
}
},"t2").start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(mq.toString());
}
}
參考文章1