阻塞队列入门
程序员文章站
2022-05-02 13:09:54
...
一.阻塞队列概述
队列包含固定长度的队列和不固定长度的队列
队列还可以分还可分为阻塞队列和不阻塞队列
-
在讲述condition时提了下BoundedBuffer,实际过程中直接用ArrayBlockingQueue这个类就行了,提供了BoundedBuffer那片代码的功能
- 查看ArrayBlockingQueue这个类,发现它实现了一个
BlockingQueue<E>
接口
- 查看ArrayBlockingQueue这个类,发现它实现了一个
如果此时你想在队列中添加元素,有三个方法add,offer,put,使用之后的效果不同
就拿Insert来说明,当有一个队列,固定长度为8,而此时队列已满,用add添加,会报错;用offer添加,会返回一个false,添加失败,成功为true
而用put就会等待,即就是阻塞了;取元素也是如此的
二.阻塞队列例子
public class BlockingQueueTest {
public static void main(String[] args) {
final BlockingQueue queue = new ArrayBlockingQueue(3);//空间大小为3
for(int i=0;i<2;i++) {
new Thread() {
public void run() {
while(true) {
try {
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName()+"准备放数据!");
queue.put(1);
System.out.println(Thread.currentThread().getName()+"已经放了数据, "+"队列目前有"+queue.size()+"个数据");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}
new Thread() {
public void run() {
while(true) {
try {
//将此处的睡眠时间分别改为100和1000,观察运行结果
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName()+"已经取走数据, "+
"队列目前有"+queue.size()+"个数据");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}
}
控制台输出
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有2个数据
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有3个数据
Thread-0准备放数据!
Thread-1准备放数据!
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有2个数据
Thread-0已经放了数据, 队列目前有3个数据
Thread-0准备放数据!
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有2个数据
Thread-1已经放了数据, 队列目前有3个数据
Thread-1准备放数据!
....
public class BlockingQueueTest {
public static void main(String[] args) {
final BlockingQueue queue = new ArrayBlockingQueue(3);//空间大小为3
for(int i=0;i<2;i++) {
new Thread() {
public void run() {
while(true) {
try {
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName()+"准备放数据!");
queue.put(1);
System.out.println(Thread.currentThread().getName()+"已经放了数据, "+"队列目前有"+queue.size()+"个数据");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}
new Thread() {
public void run() {
while(true) {
try {
Thread.sleep(100);//取得太快,会造成存入一个就立马取出来了
System.out.println(Thread.currentThread().getName()+"准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName()+"已经取走数据, "+
"队列目前有"+queue.size()+"个数据");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}.start();
}
}
控制台输出
Thread-2准备取数据!
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
Thread-0准备放数据!
Thread-0已经放了数据, 队列目前有1个数据
Thread-2已经取走数据, 队列目前有0个数据
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有0个数据
Thread-1准备放数据!
Thread-1已经放了数据, 队列目前有1个数据
Thread-2准备取数据!
Thread-2已经取走数据, 队列目前有0个数据
Thread-2准备取数据!
....