仿照阻塞队列,实现自己的阻塞队列。( ArrayBlockingQueue )
代码如下,直接复制即可
/**
* 仿照阻塞队列,实现自己的阻塞队列。( ArrayBlockingQueue )
* 中间会使用到Lock接口,ReentrantLock,Condition
*/
public class MyArrBlockingQueue {
final Lock lock = new ReentrantLock();
final Condition put_condition = lock.newCondition();
final Condition take_condition = lock.newCondition();
final Object[] items ;
int put_index, take_index, count;
public MyArrBlockingQueue(int capacity) {
items = new Object[capacity];
}
public static void main(String[] args) {
MyArrBlockingQueue queue = new MyArrBlockingQueue(10);
new Thread(() ->{//模拟往队列添加数据
try {
for (int i = 0; /*i<5 */; i+=2) {
queue.put(i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() ->{
try {
for (int i = 1; /*i<5 */; i+=2) {
queue.put(i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start(); //模拟往队列添加数据
new Thread(() ->{ //模拟取数据
try {
while (true){
queue.take();
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length){
put_condition.await();
System.out.println("队列已经满了,阻塞put() 操作!!");
}
items[put_index] = x;
System.out.println("当前队列数据:"+ Arrays.toString(items) + " 插入数据" + x );
if (++put_index == items.length)
put_index = 0;
++count;
take_condition.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
take_condition.await();
Object x = items[take_index];
if (++take_index == items.length){ //已经取到最后面的元素了
take_index = 0;
System.out.println("队列为空");
}
System.out.println("当前队列数据:"+ Arrays.toString(items) + "从队列取出" + x );
--count;
put_condition.signal();
return x;
} finally {
lock.unlock();
}
}
}