import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 使用wait和notify實現Queue
* BlockingQueue: 顧名思義,首先它是一個隊列,並且支持阻塞機制,阻塞的放入和阻塞的得到數據,
* 我們要實現LinkedBlockingQueue下面下面兩個簡單的方法put和take
* put(anObject):把把對象加到BlockingQueue裏面,如果BlockQueue沒有空間,則調用此方法的線程被阻斷
* 直到BlockingQueue裏面沒有空間在繼續。
*take():取走blockingQueue裏面該在首位的對象,若blockingQueue爲空,阻塞進入等待狀態,直到BlockingQueue有新的數據被加入
*
* wait 和notify 結合synchronized使用
*
* */
public class MyQueue {
//1.需要裝元素的集合
private final LinkedList<Object> list = new LinkedList<Object>();
/**
* 2.需要一個計數器,統計加入list幾個的個數
*AtomicInteger,一個提供原子操作的Integer的類。在Java語言中
*,++i和i++操作並不是線程安全的,在使用的時候,不可避免的會用到
*synchronized關鍵字。而AtomicInteger則通過一種線程安全的加減操作接口。
* */
private AtomicInteger count = new AtomicInteger(0);
//指定上限上限和下限
private final int minSize = 0;
private final int maxSize;
//構造方法,構造容器最大長度
public MyQueue(int size) {
this.maxSize = size;
}
public MyQueue() {
//最大長度默認爲10
this(10);
}
/**
* 初始化一個對象用於加鎖
* */
private final Object lock = new Object();
//返回長度
public int size() {
return count.get();
}
/**
* 添加一個對象,如果隊列滿了,則阻塞
* */
public void put(Object obj) {
synchronized (lock) {
//如果容器大小剛好等於最大長度,則阻塞
while(size() == maxSize) {
try {
lock.wait();//阻塞
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
list.add(obj);
count.incrementAndGet();//相當於i++
System.out.println("新加入的元素爲:"+obj);
lock.notify();//通知另外一個線程去取元素
}
}
/**
* 取出一個元素,如果隊列爲空,則阻塞
* */
public Object take() {
synchronized (lock) {
//如果容器的大小剛好等於隊列最小長度,則阻塞
while(minSize == size()) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//取出第一個元素
Object obj = list.removeFirst();
//計數器遞減
count.decrementAndGet();
lock.notify();//通知另外一個線程進行添加元素
return obj;//返回結果
}
}
public static void main(String[] args) {
final MyQueue m = new MyQueue(5);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m.put("a");
m.put("b");
m.put("c");
m.put("d");
m.put("e");
m.put("f");
}
});
t1.start();
try {
Thread.sleep(1000);
System.out.println("當前容器的大小:"+m.size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Object o = m.take();
System.out.println("取出的元素爲:"+o);
}
});
t2.start();
try {
Thread.sleep(10);
System.out.println(m.size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用java來實現阻塞隊列
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.