内部使用ArrayList作为存储容器,提供两个构造方法,可以自己指定队列容量。
一 使用synchronized锁实现
import java.util.ArrayList;
import java.util.List;
public class SelfQueue<T> {
//默认阻塞队列容量
private static int DEFAULT_CAPACITY = 3;
private List<T> list;
/**
* 无惨构造
* 使用默认容量初始化队列
*/
public SelfQueue() {
list = new ArrayList<>(DEFAULT_CAPACITY);
}
/**
* 有参构造
* 自定义队列容量
*/
public SelfQueue(int capacity) throws Exception {
DEFAULT_CAPACITY = capacity;
list = new ArrayList<>(capacity);
}
/**
* 阻塞放
*/
public void put(T t) {
synchronized (SelfQueue.class) {
while (list.size() == DEFAULT_CAPACITY) {
try {
//等待
SelfQueue.class.wait();
} catch (InterruptedException e) {
System.out.println("put error!");
}
}
//队列中元素个数少于队列容量时唤醒
if (list.size() < DEFAULT_CAPACITY) {
//唤醒
SelfQueue.class.notify();
}
list.add(t);
}
}
/**
* 阻塞取
*/
public T take() {
synchronized (SelfQueue.class) {
while (list.size() == 0) {
try {
//等待
SelfQueue.class.wait();
} catch (InterruptedException e) {
System.out.println("take error!");
}
}
//队列中元素个数大于0时唤醒
if (list.size() > 0) {
//唤醒
SelfQueue.class.notify();
}
return list.remove(0);
}
}
}
二 使用lock+condition实现
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SelfQueue<T> {
private static int CAPACITY = 3;
private List<T> list;
private Lock lock;
private Condition condition;
SelfQueue() {
this(CAPACITY);
}
SelfQueue(int capacity) {
this.CAPACITY = capacity;
list = new ArrayList<>(CAPACITY);
lock = new ReentrantLock();
condition = lock.newCondition();
}
public void put(T t) {
lock.lock();
while (list.size() == CAPACITY) {
try {
condition.await();
} catch (InterruptedException e) {
System.out.println("put error!");
}
}
if (list.size() < CAPACITY) {
condition.signal();
}
list.add(t);
lock.unlock();
}
public T take() {
lock.lock();
while (list.size() == 0) {
try {
condition.await();
} catch (InterruptedException e) {
System.out.println("put error!");
}
}
if (list.size() > 0) {
condition.signal();
}
T t = list.remove(0);
lock.unlock();
return t;
}
}