public class MyBlockingQueue<E> {
public static void main(String[] args) throws Exception {
MyBlockingQueue<Integer> blockingQueue = new MyBlockingQueue<Integer>(5);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
blockingQueue.put(1);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
blockingQueue.take();
}
}
}).start();
}
Queue<E> queue;
Integer size;
ReentrantLock lock;
Condition notFull;
Condition notEmpty;
public MyBlockingQueue(Integer size) {
this.size = size;
this.queue = new LinkedList();
this.lock = new ReentrantLock();
this.notFull = lock.newCondition();
this.notEmpty = lock.newCondition();
}
public void put(E element) {
try {
lock.lock();
while (queue.size() == size) {
notFull.await();
}
System.out.println("producer produce " + queue.size());
queue.offer(element);
notEmpty.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public E take() {
try {
lock.lock();
while (queue.size() == 0) {
notEmpty.await();
}
System.out.println("consumer consume " + queue.size());
E poll = queue.poll();
notFull.signal();
return poll;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
return null;
}
}
}