返回
从零开始打造自己的阻塞队列
后端
2023-10-10 08:34:53
1. 什么是阻塞队列?
阻塞队列是一种特殊的队列,它允许我们在队列为空时阻塞当前线程,直到队列中有数据可取时才继续执行。阻塞队列在多线程编程中非常有用,它可以帮助我们避免线程之间的竞争,并确保数据的一致性。
2. 阻塞队列的实现原理
阻塞队列的实现原理并不复杂,它主要依赖于两个基本操作:put()和take()。put()操作将数据添加到队列中,而take()操作从队列中取出数据。当队列为空时,put()操作会阻塞当前线程,直到队列中有数据可取时才继续执行。同样,当队列已满时,take()操作也会阻塞当前线程,直到队列中有空位可放时才继续执行。
3. 实现一个简单的阻塞队列
现在,我们来一步一步实现一个简单的阻塞队列。首先,我们需要创建一个队列来存储数据。我们可以使用Java的ArrayBlockingQueue类,这是一个基于数组的阻塞队列。
import java.util.concurrent.ArrayBlockingQueue;
public class BlockingQueue {
private ArrayBlockingQueue<Integer> queue;
public BlockingQueue(int capacity) {
queue = new ArrayBlockingQueue<>(capacity);
}
public void put(Integer data) throws InterruptedException {
queue.put(data);
}
public Integer take() throws InterruptedException {
return queue.take();
}
}
然后,我们需要实现put()和take()方法。put()方法将数据添加到队列中,如果队列已满,则阻塞当前线程,直到队列中有空位可放时才继续执行。
public void put(Integer data) throws InterruptedException {
while (queue.remainingCapacity() == 0) {
synchronized (this) {
wait();
}
}
queue.put(data);
synchronized (this) {
notifyAll();
}
}
take()方法从队列中取出数据,如果队列为空,则阻塞当前线程,直到队列中有数据可取时才继续执行。
public Integer take() throws InterruptedException {
while (queue.size() == 0) {
synchronized (this) {
wait();
}
}
Integer data = queue.take();
synchronized (this) {
notifyAll();
}
return data;
}
最后,我们可以创建一个BlockingQueue对象并使用它来存储和取出数据。
public class Main {
public static void main(String[] args) {
BlockingQueue queue = new BlockingQueue(10);
//生产者线程
new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
queue.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
//消费者线程
new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
Integer data = queue.take();
System.out.println(data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
通过这个简单的示例,我们实现了