阻塞队列
首先我们造一个阻塞队列,用来存放任务,当然你不想造直接用jdk的也行
阻塞队列,需要一个队列,还需要一个让他阻塞的东西(条件),我们使用ReentrantLock和他的小伙伴Condition,那么阻塞队列的成员变量如下
//容量
private int capacity;
public MyQueue(int capacity) {
this.capacity = capacity;
this.queue = new ArrayDeque<>(capacity);
}
//存放元素的队列
private Deque<T> queue;
private ReentrantLock lock = new ReentrantLock();
//等待不为满的条件变量
private Condition notFull = lock.newCondition();
//等待不为空的条件变量
private Condition notEmpty = lock.newCondition();
接下来写他的读方法
非阻塞方法get()
//非阻塞方法get
public T get() {
lock.lock();
try {
if (queue.isEmpty()) return null;
T res = queue.removeLast();
//不为满了,唤醒等待插入的线程
notFull.signal();
return res;
} finally {
lock.unlock();
}
}
阻塞等待take()
//阻塞等待
public T take() {
lock.lock();
try {
while (queue.isEmpty()) {
log.info("队列为空");
try {
//等待不为空
notEmpty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T res = queue.removeLast();
log.info("获取成功: " + res);
//不为满了,唤醒等待插入的线程
notFull.signal();
return res;
} finally {
lock.unlock();
}
}
限时阻塞等待take(long time, TimeUnit unit)
//阻塞等待
public T take() {
lock.lock();
try {
while (queue.isEmpty()) {
log.info("队列为空");
try {
//等待不为空
notEmpty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T res = queue.removeLast();
log.info("获取成功: " + res);
//不为满了,唤醒等待插入的线程
notFull.signal();
return res;
} finally {
lock.unlock();
}
}
以下是写方法
非阻塞插入offer(T t)
//非阻塞插入
public boolean offer(T t) {
lock.lock();
try {
if (queue.size() == capacity) return false;
queue.addLast(t);
//队列不为空了 唤醒
notEmpty.signal();
return true;
} finally {
lock.unlock();
}
}
阻塞插入put(T t)
//阻塞插入
public void put(T t) {
lock.lock();
try {
while (queue.size() == capacity) {
log.info("队列为满");
try {
//队列满了,等待
notFull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.addLast(t);
log.info("插入成功: " + t);
//队列不为空了 唤醒
notEmpty.signal();
} finally {
lock.unlock();
}
}
限时阻塞插入put(T t, long time, TimeUnit unit)
//阻塞限时插入
public boolean put(T t, long time, TimeUnit unit) {
lock.lock();
try {
long wait = unit.toNanos(time);
while (queue.size() == capacity) {
if (wait <= 0) {
log.info("插入超时: " + t);
return false;
}
//等待不满
try {
wait = notFull.awaitNanos(wait);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.addLast(t);
log.info("插入成功: " + t);
//队列不为空了 唤醒
notEmpty.signal();
return true;
} finally {
lock.unlock();
}
}
撸完了测试下代码写的对不对
MyQueue<Integer> myQueue = new MyQueue<>(2);
for (int i = 1; i <= 10; i++) {
int j = i;
new Thread(() -> {