BlockingQueue 的各个存取方法是否阻塞,请列出一个表格,展示各个api 是否阻塞,是否有异常
时间: 2024-04-21 16:24:49 浏览: 10
| 方法 | 是否阻塞 | 是否有异常 |
|-------------------|---------|-------------------|
| add(E e) | 否 | IllegalStateException |
| offer(E e) | 否 | 无 |
| put(E e) | 是 | 无 |
| poll() | 否 | 无 |
| take() | 是 | InterruptedException |
| remove(Object o) | 否 | 无 |
| contains(Object o)| 否 | 无 |
在上表中,"是否阻塞"一栏表示方法是否会在操作不可立即完成时阻塞当前线程,"是否有异常"一栏表示方法在特定条件下是否会抛出异常。
相关问题
请用ReentrantLock和Condition实现一个简单的阻塞队列
好的,我可以为你实现一个基于ReentrantLock和Condition的简单阻塞队列。
首先,我们需要定义一个队列类,包含以下方法:
- `enqueue(item)`:将元素放入队列中。
- `dequeue()`:从队列中取出元素。
- `size()`:返回队列的大小。
下面是使用ReentrantLock和Condition实现的代码:
```java
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class BlockingQueue<T> {
private Queue<T> queue;
private int maxSize;
private ReentrantLock lock;
private Condition notEmpty;
private Condition notFull;
public BlockingQueue(int maxSize) {
this.maxSize = maxSize;
this.queue = new LinkedList<>();
this.lock = new ReentrantLock();
this.notEmpty = lock.newCondition();
this.notFull = lock.newCondition();
}
public void enqueue(T item) throws InterruptedException {
lock.lock();
try {
while (queue.size() == maxSize) { // 队列已满,等待直到队列不满
notFull.await();
}
queue.add(item);
notEmpty.signalAll(); // 通知等待中的线程队列不为空
} finally {
lock.unlock();
}
}
public T dequeue() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) { // 队列为空,等待直到队列不为空
notEmpty.await();
}
T item = queue.remove();
notFull.signalAll(); // 通知等待中的线程队列不满
return item;
} finally {
lock.unlock();
}
}
public int size() {
lock.lock();
try {
return queue.size();
} finally {
lock.unlock();
}
}
}
```
使用这个阻塞队列的示例代码如下:
```java
public class Main {
public static void main(String[] args) {
BlockingQueue<Integer> queue = new BlockingQueue<>(5);
Thread producer = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
queue.enqueue(i);
System.out.println("Produced: " + i);
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
int item = queue.dequeue();
System.out.println("Consumed: " + item);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producer.start();
consumer.start();
}
}
```
在这个示例中,生产者线程不断地将元素放入队列中,消费者线程不断地从队列中取出元素。当队列已满时,生产者线程会被阻塞,直到有空余位置;当队列为空时,消费者线程会被阻塞,直到有元素可取。
希望这个简单的阻塞队列的实现对你有帮助!如果还有其他问题,请继续提问。
请编写一个程序,基于LinkedList实现阻塞队列(可参考LinkedBlockingQueue源码)
好的,我会尽力回答您的问题。以下是基于LinkedList实现阻塞队列的示例代码:
```java
import java.util.LinkedList;
public class BlockingQueue<T> {
private LinkedList<T> queue = new LinkedList<>();
private int capacity;
public BlockingQueue(int capacity) {
this.capacity = capacity;
}
public synchronized void put(T element) throws InterruptedException {
while (queue.size() == capacity) {
wait();
}
queue.add(element);
notifyAll();
}
public synchronized T take() throws InterruptedException {
while (queue.isEmpty()) {
wait();
}
T element = queue.remove();
notifyAll();
return element;
}
}
```
这个阻塞队列类有一个包含容量参数的构造函数。 `put` 方法在队列满时会阻塞,直到队列有空间可用为止。 `take` 方法在队列为空时会阻塞,直到有元素可供取出为止。在 `put` 和 `take` 方法中使用 `wait` 和 `notifyAll` 实现了阻塞和唤醒的逻辑。
希望这个示例代码可以帮助到您!