package com.reentrant;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ArrayBlockingQueue<E> {
private Lock lock;
private Condition NotNull;
private Condition NotFull;
private int capacity;
private int rear;
private int front;
private int size;
private Object[] items;
public int size(){
lock.lock();
try {
return this.size;
} finally {
lock.unlock();
}
}
public ArrayBlockingQueue(int capacity){
this.capacity = capacity;
lock = new ReentrantLock();
NotNull = lock.newCondition();
NotFull = lock.newCondition();
items = new Object[capacity];
size = rear = front = 0;
}
public E put(E e) throws InterruptedException{
lock.lock();
try{
while
(capacity == size){
NotFull.await();
}
items[rear] = e;
if(++rear == items.length){
rear = 0;
}
size++;
System.out.printf("当前put线程=%s,生产的元素=%s,生产之后队列长度=%d,%n",Thread.currentThread().getName(),e,size());
Thread.sleep(1000);
NotNull.signalAll();
return e;
}finally{
lock.unlock();
}
}
public E take() throws InterruptedException{
lock.lock();
try{
while
(0 == size){
NotNull.await();
}
Object x = items[front];
items[front] = null;
if(++front == items.length){
front = 0;
}
size--;
System.out.printf("当前take线程=%s,消费的元素=%s,消费之后队列长度=%d,%n",Thread.currentThread().getName(),x,size());
Thread.sleep(1000);
NotFull.signalAll();
return (E)x;
}finally{
lock.unlock();
}
}
}
package com.reentrant;
public class ArrayBlockingQueueApp {
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
Runnable taketask1 = ()->{
while(true){
try {
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable taketask2 = ()->{
while(true){
try {
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable puttask1 = ()->{
int i = 0;
while(true){
try {
queue.put(i+"");
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
};
Thread take1 = new Thread(taketask1,"[消费者1]");
Thread take2 = new Thread(taketask2,"[消费者2]");
Thread put1 = new Thread(puttask1,"[生产者1]");
take2.start();
put1.start();
take1.start();
}
}