一、BlockingQueue支持阻塞隊列
此例子主要是模擬LinkBlockingQueue中put和take方法
public class SimulationQueue {
// 1 裝載元素的容器
private final List<Object> list = Lists.newArrayList();
// 2 計數器
private final AtomicInteger count = new AtomicInteger(0);
// 3 確定容器的上限和下限
private Integer maxSize;
private Integer minSize;
// 4 構造初始值
public SimulationQueue(int maxSize) {
this.maxSize = maxSize;
}
// 5 初始化一個對象,用於加鎖
private Object lock = new Object();
/**
* put(an object) 把an object加到BlockingQueue裏面,如果BlockingQueue沒有空間
* 調用此方法的線程被阻斷,直到BlockingQueue,有空間添加數據
*
* @param obj
*/
public void put(Object obj) {
synchronized (lock) {
while (count.get() == maxSize) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 1 容器中添加元素
list.add(obj);
// 2 計數器加1
count.incrementAndGet();
System.out.println("新加入的元素爲:" + obj);
// 3 通知其他線程(喚醒)
lock.notify();
}
}
/**
* take() 取走排在BlockingQueue裏面排在首位的元素,如果BlockingQueue爲空
* 阻斷進入等待狀態,直到BlockingQueue有新的數據加入
*/
public Object take() {
Object ret = null;
synchronized (lock) {
while (count.get() == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 1 容器中取出排在首位的元素
Object firstObj = list.remove(0);
// 2 計數器遞減
count.decrementAndGet();
// 3 通知其他線程(喚醒)
lock.notify();
}
return ret;
}
public int size() {
return count.get();
}
public static void main(String[] args) throws Exception {
final SimulationQueue m = new SimulationQueue(5);
m.put("a");
m.put("b");
m.put("c");
m.put("d");
m.put("e");
System.out.println("當前元素個數:" + m.size());
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m.put("h");
m.put("i");
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
Object t1 = m.take();
//System.out.println("被取走的元素爲:" + t1);
Thread.sleep(1000);
Object t2 = m.take();
//System.out.println("被取走的元素爲:" + t2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t2");
t1.start();
Thread.sleep(1000);
t2.start();
}
}