为了简化一些队列的开发难度,JUC提供了两个新的阻塞队列接口:
- BlockingQueue:单端队列
- BlockingDeque:双端队列
BlockingQueue有以下几个子类:
- ArrayBlockingQueue(数组结构):是一个利用数组控制形式实现的队列操作,需要在其实例化时直接提供数组的长度,也可以设置阻塞线程的公平与非公平抢占原则。
- LinkedBlockingQueue(链表单端阻塞队列)
- PriorityBlockingQueue(优先级阻塞队列)
- SynchronousQueue(同步队列)
1、使用ArrayBlockingQueue【数组结构】实现生产者与消费者模型的例子:
package com.mydemo;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class JUCDemo {
public static void main(String[] args) throws InterruptedException {
// 设置2个队列容量
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
// 循环创建线程---生产者线程
for(int i = 0; i < 3; i++){
new Thread(()->{
for(int j = 0; j < 5; j++){
try {
// 操作延迟
TimeUnit.SECONDS.sleep(2);
// 定义信息
String msg = "【" + Thread.currentThread().getName() + "】生产数据 = " + j;
// 队列保存数据
blockingQueue.put(msg);
// 提示信息:
System.out.println("{生产数据}" + msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}, "生产者线程-" + i).start();
}
// 循环创建线程---消费者线程
for(int i = 0; i < 2; i++){
new Thread(()->{
while (true){
try {
// 延迟操作
TimeUnit.SECONDS.sleep(1);
// 消费数据
System.err.println("==================");
System.err.println(blockingQueue.take());
} catch (Exception e) {
e.printStackTrace();
}
}
}, "消费者线程-" + i).start();
}
}
}
2、使用LinkedBlockingQueue【链表单端阻塞队列】实现生产者与消费者模型的例子:
/**
* 注意点:
* 使用链表结构的阻塞队列默认情况下允许保存的数据长度为Integer.MAX_VALUE
*
* 该处设置2个队列容量
*/
BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(2);
// 其他重复同1。。。
3、使用PriorityBlockingQueue【优先级阻塞队列】实现生产者与消费者模型的例子:
/**
* 优先级阻塞队列拥有数据排序的支持,
* 所以通过其无参构造实例化队列的默认保存数据长度为11个内容,
* 这样在消费时会按照数据顺序获取内容。
*/
BlockingQueue<String> blockingQueue = new PriorityBlockingQueue<>();
// 其他重复同1。。。
4、使用SynchronousQueue【同步队列】实现生产者与消费者模型的例子:
/**
* 在多数情况下有可能只需存储一个数据,
* 所以此时就可以通过同步阻塞队列来完成。
* 使用同步队列操作的时候没有容量的概念,
* 因为它只允许保存一个信息。
*
*
* 由于该程序只允许在队列中保存一个数据内容,
* 所有的生产者就需要通过资源的竞争才可以实现队列数据的保存。
*/
BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
// 其他重复同1。。。